private void DrawFileListTab() { if (!ImGui.BeginTabItem(LabelFileListTab)) { return; } using var raii = ImGuiRaii.DeferredEnd(ImGui.EndTabItem); ImGuiCustom.HoverTooltip(TooltipFilesTab); ImGui.SetNextItemWidth(-1); if (ImGui.BeginListBox(LabelFileListHeader, AutoFillSize)) { raii.Push(ImGui.EndListBox); UpdateFilenameList(); using var colorRaii = new ImGuiRaii.Color(); foreach (var(name, _, color, _) in _fullFilenameList !) { colorRaii.Push(ImGuiCol.Text, color); ImGui.Selectable(name.FullName); colorRaii.Pop(); } } else { _fullFilenameList = null; } }
private void DrawAboutTab() { if (!_editMode && Meta.Description.Length == 0) { return; } if (!ImGui.BeginTabItem(LabelAboutTab)) { return; } using var raii = ImGuiRaii.DeferredEnd(ImGui.EndTabItem); var desc = Meta.Description; var flags = _editMode ? ImGuiInputTextFlags.EnterReturnsTrue | ImGuiInputTextFlags.CtrlEnterForNewLine : ImGuiInputTextFlags.ReadOnly; if (_editMode) { if (ImGui.InputTextMultiline(LabelDescEdit, ref desc, 1 << 16, AutoFillSize, flags)) { Meta.Description = desc; _selector.SaveCurrentMod(); } ImGuiCustom.HoverTooltip(TooltipAboutEdit); } else { ImGui.TextWrapped(desc); } }
private static bool ImageButtonImpl(Texture texture, FloatRect textureRect, Vector2f size, int framePadding, Color bgColor, Color tintColor) { var textureSize = texture.Size; var uv0 = new Vector2(textureRect.Left / textureSize.X, textureRect.Top / textureSize.Y); var uv1 = new Vector2((textureRect.Left + textureRect.Width) / textureSize.X, (textureRect.Top + textureRect.Height) / textureSize.Y); var textureId = ConvertGlTextureHandleToImTextureId(texture.NativeHandle); return(ImGui.ImageButton(textureId, new Vector2(size.X, size.Y), uv0, uv1, framePadding, ToImColor(bgColor).Value, ToImColor(tintColor).Value)); }
public static void Shutdown() { ImGui.GetIO().Fonts.TexID = IntPtr.Zero; _fontTexture.Dispose(); for (var i = 0; i < (int)ImGuiMouseCursor.COUNT; ++i) { if (_mouseCursors[i] != null) { _mouseCursors[i].Dispose(); } } ImGui.DestroyContext(); }
public void Begin(int count, float items_height = -1.0f) { StartPosY = ImGuiNative.igGetCursorPosY(); ItemsHeight = items_height; ItemsCount = count; StepNo = 0; DisplayEnd = DisplayStart = -1; if (ItemsHeight > 0.0f) { ImGui.CalcListClipping(ItemsCount, ItemsHeight, ref DisplayStart, ref DisplayEnd); // calculate how many to clip/display if (DisplayStart > 0) //SetCursorPosYAndSetupDummyPrevLine(StartPosY + DisplayStart * ItemsHeight, ItemsHeight); // advance cursor ImGuiNative.igSetCursorPosY(StartPosY + DisplayStart * ItemsHeight); StepNo = 2; } }
public static void UpdateFontTexture() { var io = ImGui.GetIO(); io.Fonts.GetTexDataAsRGBA32(out IntPtr pixels, out var width, out var height, out var bpp); _fontTexture = new Texture((uint)width, (uint)height); var size = width * height * bpp; var byteArray = new byte[size]; Marshal.Copy(pixels, byteArray, 0, size); _fontTexture.Update(byteArray); io.Fonts.SetTexID(ConvertGlTextureHandleToImTextureId(_fontTexture.NativeHandle)); }
private static void OnMouseWheelScrolled(object sender, MouseWheelScrollEventArgs args) { var io = ImGui.GetIO(); switch (args.Wheel) { case Mouse.Wheel.VerticalWheel: case Mouse.Wheel.HorizontalWheel when io.KeyShift: io.MouseWheel += args.Delta; break; case Mouse.Wheel.HorizontalWheel: io.MouseWheelH += args.Delta; break; default: throw new ArgumentOutOfRangeException(); } }
private void DrawChangedItemsTab() { if (Mod.Data.ChangedItems.Count == 0 || !ImGui.BeginTabItem(LabelChangedItemsTab)) { return; } using var raii = ImGuiRaii.DeferredEnd(ImGui.EndTabItem); if (!ImGui.BeginListBox(LabelChangedItemsHeader, AutoFillSize)) { return; } raii.Push(ImGui.EndListBox); foreach (var(name, data) in Mod.Data.ChangedItems) { _base.DrawChangedItem(name, data); } }
private void DrawConflictTab() { if (!Mod.Cache.Conflicts.Any() || !ImGui.BeginTabItem(LabelConflictsTab)) { return; } using var raii = ImGuiRaii.DeferredEnd(ImGui.EndTabItem); ImGui.SetNextItemWidth(-1); if (!ImGui.BeginListBox(LabelConflictsHeader, AutoFillSize)) { return; } raii.Push(ImGui.EndListBox); using var indent = ImGuiRaii.PushIndent(0); foreach (var(mod, (files, manipulations)) in Mod.Cache.Conflicts) { if (ImGui.Selectable(mod.Data.Meta.Name)) { _selector.SelectModByDir(mod.Data.BasePath.Name); } ImGui.SameLine(); ImGui.Text($"(Priority {mod.Settings.Priority})"); indent.Push(15f); foreach (var file in files) { ImGui.Selectable(file); } foreach (var manip in manipulations) { ImGui.Text(manip.IdentifierString()); } indent.Pop(15f); } }
/// <summary> /// Constructs a new ImGuiController. /// </summary> public ImGuiController(GraphicsDevice gd, OutputDescription outputDescription, int width, int height) { _gd = gd; _windowWidth = width; _windowHeight = height; IntPtr context = ImGui.CreateContext(); ImGui.SetCurrentContext(context); var fonts = ImGui.GetIO().Fonts; ImGui.GetIO().Fonts.AddFontDefault(); CreateDeviceResources(gd, outputDescription); SetKeyMappings(); SetPerFrameImGuiData(1f / 60f); ImGui.NewFrame(); _frameBegun = true; }
// Taken from https://github.com/ocornut/imgui/issues/1496#issuecomment-655048353 private static void BeginGroupPanel(string name, Vector2 size) { ImGui.BeginGroup(); var cursorPos = ImGui.GetCursorScreenPos(); var itemSpacing = ImGui.GetStyle().ItemSpacing; ImGui.PushStyleVar(ImGuiStyleVar.FramePadding, 0f); ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, 0f); var frameHeight = ImGui.GetFrameHeight(); ImGui.BeginGroup(); Vector2 effectiveSize = size; if (size.X < 0.0f) { effectiveSize.X = ImGui.GetContentRegionAvail().X; } else { effectiveSize.X = size.X; } ImGui.Dummy(new Vector2(effectiveSize.X, 0.0f)); ImGui.Dummy(new Vector2(frameHeight * 0.5f, 0.0f)); ImGui.SameLine(0.0f, 0.0f); ImGui.BeginGroup(); ImGui.Dummy(new Vector2(frameHeight * 0.5f, 0.0f)); ImGui.SameLine(0.0f, 0.0f); ImGui.TextUnformatted(name); var labelMin = ImGui.GetItemRectMin(); var labelMax = ImGui.GetItemRectMax(); ImGui.SameLine(0.0f, 0.0f); ImGui.Dummy(new Vector2(0.0f, frameHeight + itemSpacing.Y)); ImGui.BeginGroup(); ImGui.PopStyleVar(2); }
public static void Image(Sprite sprite, Vector2f size, Color tintColor, Color borderColor) { var texture = sprite.Texture; // sprite without texture cannot be drawn if (texture is null) { return; } var textureSize = (Vector2f)texture.Size; var textureRect = sprite.TextureRect; var uv0 = new Vector2(textureRect.Left / textureSize.X, textureRect.Top / textureSize.Y); var uv1 = new Vector2((textureRect.Left + textureRect.Width) / textureSize.X, (textureRect.Top + textureRect.Height) / textureSize.Y); var textureId = ConvertGlTextureHandleToImTextureId(texture.NativeHandle); ImGui.Image(textureId, new Vector2(size.X, size.Y), uv0, uv1, ToImColor(tintColor).Value, ToImColor(borderColor).Value); }
private void DrawFileSwapTab() { if (_editMode) { DrawFileSwapTabEdit(); return; } if (!Meta.FileSwaps.Any() || !ImGui.BeginTabItem(LabelFileSwapTab)) { return; } using var raii = ImGuiRaii.DeferredEnd(ImGui.EndTabItem); const ImGuiTableFlags flags = ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.RowBg | ImGuiTableFlags.ScrollX; ImGui.SetNextItemWidth(-1); if (!ImGui.BeginTable(LabelFileSwapHeader, 3, flags, AutoFillSize)) { return; } raii.Push(ImGui.EndTable); foreach (var(source, target) in Meta.FileSwaps) { ImGui.TableNextColumn(); ImGuiCustom.CopyOnClickSelectable(source); ImGui.TableNextColumn(); ImGuiCustom.PrintIcon(FontAwesomeIcon.LongArrowAltRight); ImGui.TableNextColumn(); ImGuiCustom.CopyOnClickSelectable(target); ImGui.TableNextRow(); } }
private static void UpdateMouseCursor(Window window) { var io = ImGui.GetIO(); if ((io.ConfigFlags & ImGuiConfigFlags.NoMouseCursorChange) != 0) { return; } var cursor = ImGui.GetMouseCursor(); if (io.MouseDrawCursor || cursor == ImGuiMouseCursor.None) { window.SetMouseCursorVisible(false); } else { window.SetMouseCursorVisible(true); var sfmlCursor = _mouseCursors[(int)cursor] ?? _mouseCursors[(int)ImGuiMouseCursor.Arrow]; window.SetMouseCursor(sfmlCursor); } }
private void RenderImDrawData(ImDrawDataPtr draw_data, GraphicsDevice gd, CommandList cl) { uint vertexOffsetInVertices = 0; uint indexOffsetInElements = 0; if (draw_data.CmdListsCount == 0) { return; } uint totalVBSize = (uint)(draw_data.TotalVtxCount * Unsafe.SizeOf <ImDrawVert>()); if (totalVBSize > _vertexBuffer.SizeInBytes) { gd.DisposeWhenIdle(_vertexBuffer); _vertexBuffer = gd.ResourceFactory.CreateBuffer(new BufferDescription((uint)(totalVBSize * 1.5f), BufferUsage.VertexBuffer | BufferUsage.Dynamic)); } uint totalIBSize = (uint)(draw_data.TotalIdxCount * sizeof(ushort)); if (totalIBSize > _indexBuffer.SizeInBytes) { gd.DisposeWhenIdle(_indexBuffer); _indexBuffer = gd.ResourceFactory.CreateBuffer(new BufferDescription((uint)(totalIBSize * 1.5f), BufferUsage.IndexBuffer | BufferUsage.Dynamic)); } for (int i = 0; i < draw_data.CmdListsCount; i++) { ImDrawListPtr cmd_list = draw_data.CmdListsRange[i]; cl.UpdateBuffer( _vertexBuffer, vertexOffsetInVertices * (uint)Unsafe.SizeOf <ImDrawVert>(), cmd_list.VtxBuffer.Data, (uint)(cmd_list.VtxBuffer.Size * Unsafe.SizeOf <ImDrawVert>())); cl.UpdateBuffer( _indexBuffer, indexOffsetInElements * sizeof(ushort), cmd_list.IdxBuffer.Data, (uint)(cmd_list.IdxBuffer.Size * sizeof(ushort))); vertexOffsetInVertices += (uint)cmd_list.VtxBuffer.Size; indexOffsetInElements += (uint)cmd_list.IdxBuffer.Size; } // Setup orthographic projection matrix into our constant buffer ImGuiIOPtr io = ImGui.GetIO(); Matrix4x4 mvp = Matrix4x4.CreateOrthographicOffCenter( 0f, io.DisplaySize.X, io.DisplaySize.Y, 0.0f, -1.0f, 1.0f); _gd.UpdateBuffer(_projMatrixBuffer, 0, ref mvp); cl.SetVertexBuffer(0, _vertexBuffer); cl.SetIndexBuffer(_indexBuffer, IndexFormat.UInt16); cl.SetPipeline(_pipeline); cl.SetGraphicsResourceSet(0, _mainResourceSet); draw_data.ScaleClipRects(io.DisplayFramebufferScale); // Render command lists int vtx_offset = 0; int idx_offset = 0; for (int n = 0; n < draw_data.CmdListsCount; n++) { ImDrawListPtr cmd_list = draw_data.CmdListsRange[n]; for (int cmd_i = 0; cmd_i < cmd_list.CmdBuffer.Size; cmd_i++) { ImDrawCmdPtr pcmd = cmd_list.CmdBuffer[cmd_i]; if (pcmd.UserCallback != IntPtr.Zero) { throw new NotImplementedException(); } else { if (pcmd.TextureId != IntPtr.Zero) { if (pcmd.TextureId == _fontAtlasID) { cl.SetGraphicsResourceSet(1, _fontTextureResourceSet); } else { cl.SetGraphicsResourceSet(1, GetImageResourceSet(pcmd.TextureId)); } } cl.SetScissorRect( 0, (uint)pcmd.ClipRect.X, (uint)pcmd.ClipRect.Y, (uint)(pcmd.ClipRect.Z - pcmd.ClipRect.X), (uint)(pcmd.ClipRect.W - pcmd.ClipRect.Y)); cl.DrawIndexed(pcmd.ElemCount, 1, (uint)idx_offset, vtx_offset, 0); } idx_offset += (int)pcmd.ElemCount; } vtx_offset += cmd_list.VtxBuffer.Size; } }
private void UpdateImGuiInput(InputSnapshot snapshot) { ImGuiIOPtr io = ImGui.GetIO(); Vector2 mousePosition = snapshot.MousePosition; // Determine if any of the mouse buttons were pressed during this snapshot period, even if they are no longer held. bool leftPressed = false; bool middlePressed = false; bool rightPressed = false; foreach (MouseEvent me in snapshot.MouseEvents) { if (me.Down) { switch (me.MouseButton) { case MouseButton.Left: leftPressed = true; break; case MouseButton.Middle: middlePressed = true; break; case MouseButton.Right: rightPressed = true; break; } } } io.MouseDown[0] = leftPressed || snapshot.IsMouseDown(MouseButton.Left); io.MouseDown[1] = rightPressed || snapshot.IsMouseDown(MouseButton.Right); io.MouseDown[2] = middlePressed || snapshot.IsMouseDown(MouseButton.Middle); io.MousePos = mousePosition; io.MouseWheel = snapshot.WheelDelta; IReadOnlyList <char> keyCharPresses = snapshot.KeyCharPresses; for (int i = 0; i < keyCharPresses.Count; i++) { char c = keyCharPresses[i]; io.AddInputCharacter(c); } IReadOnlyList <KeyEvent> keyEvents = snapshot.KeyEvents; for (int i = 0; i < keyEvents.Count; i++) { KeyEvent keyEvent = keyEvents[i]; io.KeysDown[(int)keyEvent.Key] = keyEvent.Down; if (keyEvent.Key == Key.ControlLeft) { _controlDown = keyEvent.Down; } if (keyEvent.Key == Key.ShiftLeft) { _shiftDown = keyEvent.Down; } if (keyEvent.Key == Key.AltLeft) { _altDown = keyEvent.Down; } if (keyEvent.Key == Key.WinLeft) { _winKeyDown = keyEvent.Down; } } io.KeyCtrl = _controlDown; io.KeyAlt = _altDown; io.KeyShift = _shiftDown; io.KeySuper = _winKeyDown; }
private static Vector2 GetDownRightAbsolute(FloatRect rect) { var pos = ImGui.GetCursorScreenPos(); return(new Vector2(rect.Left + rect.Width + pos.X, rect.Top + rect.Height + pos.Y)); }
private static Vector2 GetTopLeftAbsolute(FloatRect rect) { var pos = ImGui.GetCursorScreenPos(); return(new Vector2(rect.Left + pos.X, rect.Top + pos.Y)); }
public static void Render() { ImGui.Render(); RenderDrawLists(ImGui.GetDrawData(), ImGui.GetIO()); }
public static void Render(RenderTarget target) { target.ResetGLStates(); ImGui.Render(); RenderDrawLists(ImGui.GetDrawData(), ImGui.GetIO()); }
private static void OnKeyReleased(object sender, KeyEventArgs args) { var io = ImGui.GetIO(); io.KeysDown[(int)args.Code] = false; }
private static unsafe void SubmitUI() { // Demo code adapted from the official Dear ImGui demo program: // https://github.com/ocornut/imgui/blob/master/examples/example_win32_directx11/main.cpp#L172 // 1. Show a simple window. // Tip: if we don't call ImGui.BeginWindow()/ImGui.EndWindow() the widgets automatically appears in a window called "Debug". { ImGui.Text("Hello, world!"); // Display some text (you can use a format string too) ImGui.SliderFloat("float", ref _f, 0, 1, _f.ToString("0.000")); // Edit 1 float using a slider from 0.0f to 1.0f //ImGui.ColorEdit3("clear color", ref _clearColor); // Edit 3 floats representing a color ImGui.Text($"Mouse position: {ImGui.GetMousePos()}"); ImGui.Checkbox("Demo Window", ref _showDemoWindow); // Edit bools storing our windows open/close state ImGui.Checkbox("Another Window", ref _showAnotherWindow); ImGui.Checkbox("Memory Editor", ref _showMemoryEditor); if (ImGui.Button("Button")) // Buttons return true when clicked (NB: most widgets return true when edited/activated) { _counter++; } ImGui.SameLine(0, -1); ImGui.Text($"counter = {_counter}"); ImGui.DragInt("Draggable Int", ref _dragInt); float framerate = ImGui.GetIO().Framerate; ImGui.Text($"Application average {1000.0f / framerate:0.##} ms/frame ({framerate:0.#} FPS)"); } // 2. Show another simple window. In most cases you will use an explicit Begin/End pair to name your windows. if (_showAnotherWindow) { ImGui.Begin("Another Window", ref _showAnotherWindow); ImGui.Text("Hello from another window!"); if (ImGui.Button("Close Me")) { _showAnotherWindow = false; } ImGui.End(); } // 3. Show the ImGui demo window. Most of the sample code is in ImGui.ShowDemoWindow(). Read its code to learn more about Dear ImGui! if (_showDemoWindow) { // Normally user code doesn't need/want to call this because positions are saved in .ini file anyway. // Here we just want to make the demo initial state a bit more friendly! ImGui.SetNextWindowPos(new Vector2(650, 20), ImGuiCond.FirstUseEver); ImGui.ShowDemoWindow(ref _showDemoWindow); } if (ImGui.TreeNode("Tabs")) { if (ImGui.TreeNode("Basic")) { ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags.None; if (ImGui.BeginTabBar("MyTabBar", tab_bar_flags)) { if (ImGui.BeginTabItem("Avocado")) { ImGui.Text("This is the Avocado tab!\nblah blah blah blah blah"); ImGui.EndTabItem(); } if (ImGui.BeginTabItem("Broccoli")) { ImGui.Text("This is the Broccoli tab!\nblah blah blah blah blah"); ImGui.EndTabItem(); } if (ImGui.BeginTabItem("Cucumber")) { ImGui.Text("This is the Cucumber tab!\nblah blah blah blah blah"); ImGui.EndTabItem(); } ImGui.EndTabBar(); } ImGui.Separator(); ImGui.TreePop(); } if (ImGui.TreeNode("Advanced & Close Button")) { // Expose a couple of the available flags. In most cases you may just call BeginTabBar() with no flags (0). ImGui.CheckboxFlags("ImGuiTabBarFlags_Reorderable", ref s_tab_bar_flags, (uint)ImGuiTabBarFlags.Reorderable); ImGui.CheckboxFlags("ImGuiTabBarFlags_AutoSelectNewTabs", ref s_tab_bar_flags, (uint)ImGuiTabBarFlags.AutoSelectNewTabs); ImGui.CheckboxFlags("ImGuiTabBarFlags_NoCloseWithMiddleMouseButton", ref s_tab_bar_flags, (uint)ImGuiTabBarFlags.NoCloseWithMiddleMouseButton); if ((s_tab_bar_flags & (uint)ImGuiTabBarFlags.FittingPolicyMask) == 0) { s_tab_bar_flags |= (uint)ImGuiTabBarFlags.FittingPolicyDefault; } if (ImGui.CheckboxFlags("ImGuiTabBarFlags_FittingPolicyResizeDown", ref s_tab_bar_flags, (uint)ImGuiTabBarFlags.FittingPolicyResizeDown)) { s_tab_bar_flags &= ~((uint)ImGuiTabBarFlags.FittingPolicyMask ^ (uint)ImGuiTabBarFlags.FittingPolicyResizeDown); } if (ImGui.CheckboxFlags("ImGuiTabBarFlags_FittingPolicyScroll", ref s_tab_bar_flags, (uint)ImGuiTabBarFlags.FittingPolicyScroll)) { s_tab_bar_flags &= ~((uint)ImGuiTabBarFlags.FittingPolicyMask ^ (uint)ImGuiTabBarFlags.FittingPolicyScroll); } // Tab Bar string[] names = { "Artichoke", "Beetroot", "Celery", "Daikon" }; for (int n = 0; n < s_opened.Length; n++) { if (n > 0) { ImGui.SameLine(); } ImGui.Checkbox(names[n], ref s_opened[n]); } // Passing a bool* to BeginTabItem() is similar to passing one to Begin(): the underlying bool will be set to false when the tab is closed. if (ImGui.BeginTabBar("MyTabBar", (ImGuiTabBarFlags)s_tab_bar_flags)) { for (int n = 0; n < s_opened.Length; n++) { if (s_opened[n] && ImGui.BeginTabItem(names[n], ref s_opened[n])) { ImGui.Text($"This is the {names[n]} tab!"); if ((n & 1) != 0) { ImGui.Text("I am an odd tab."); } ImGui.EndTabItem(); } } ImGui.EndTabBar(); } ImGui.Separator(); ImGui.TreePop(); } ImGui.TreePop(); } ImGuiIOPtr io = ImGui.GetIO(); SetThing(out io.DeltaTime, 2f); if (_showMemoryEditor) { _memoryEditor.Draw("Memory Editor", _memoryEditorData, _memoryEditorData.Length); } }
public static void Init(Window window, Vector2f displaySize, bool loadDefaultFont = true) { ImGui.CreateContext(); var io = ImGui.GetIO(); // tell ImGui which features we support io.BackendFlags |= ImGuiBackendFlags.HasGamepad; io.BackendFlags |= ImGuiBackendFlags.HasMouseCursors; io.BackendFlags |= ImGuiBackendFlags.HasSetMousePos; // init keyboard mapping io.KeyMap[(int)ImGuiKey.Tab] = (int)Keyboard.Key.Tab; io.KeyMap[(int)ImGuiKey.LeftArrow] = (int)Keyboard.Key.Left; io.KeyMap[(int)ImGuiKey.RightArrow] = (int)Keyboard.Key.Right; io.KeyMap[(int)ImGuiKey.UpArrow] = (int)Keyboard.Key.Up; io.KeyMap[(int)ImGuiKey.DownArrow] = (int)Keyboard.Key.Down; io.KeyMap[(int)ImGuiKey.PageUp] = (int)Keyboard.Key.PageUp; io.KeyMap[(int)ImGuiKey.PageDown] = (int)Keyboard.Key.PageDown; io.KeyMap[(int)ImGuiKey.Home] = (int)Keyboard.Key.Home; io.KeyMap[(int)ImGuiKey.End] = (int)Keyboard.Key.End; io.KeyMap[(int)ImGuiKey.Insert] = (int)Keyboard.Key.Insert; io.KeyMap[(int)ImGuiKey.Delete] = (int)Keyboard.Key.Delete; io.KeyMap[(int)ImGuiKey.Backspace] = (int)Keyboard.Key.Backspace; io.KeyMap[(int)ImGuiKey.Space] = (int)Keyboard.Key.Space; io.KeyMap[(int)ImGuiKey.Enter] = (int)Keyboard.Key.Enter; io.KeyMap[(int)ImGuiKey.Escape] = (int)Keyboard.Key.Escape; io.KeyMap[(int)ImGuiKey.A] = (int)Keyboard.Key.A; io.KeyMap[(int)ImGuiKey.C] = (int)Keyboard.Key.C; io.KeyMap[(int)ImGuiKey.V] = (int)Keyboard.Key.V; io.KeyMap[(int)ImGuiKey.X] = (int)Keyboard.Key.X; io.KeyMap[(int)ImGuiKey.Y] = (int)Keyboard.Key.Y; io.KeyMap[(int)ImGuiKey.Z] = (int)Keyboard.Key.Z; JoystickId = GetConnectedJoystickId(); for (var i = 0u; i < (uint)ImGuiNavInput.COUNT; ++i) { _joystickMapping[i] = _nullJoystickButton; } InitDefaultJoystickMapping(); // init rendering io.DisplaySize = new Vector2(displaySize.X, displaySize.Y); LoadMouseCursor(ImGuiMouseCursor.Arrow, Cursor.CursorType.Arrow); LoadMouseCursor(ImGuiMouseCursor.TextInput, Cursor.CursorType.Text); LoadMouseCursor(ImGuiMouseCursor.ResizeAll, Cursor.CursorType.SizeAll); LoadMouseCursor(ImGuiMouseCursor.ResizeNS, Cursor.CursorType.SizeVertical); LoadMouseCursor(ImGuiMouseCursor.ResizeEW, Cursor.CursorType.SizeHorinzontal); LoadMouseCursor(ImGuiMouseCursor.ResizeNESW, Cursor.CursorType.SizeBottomLeftTopRight); LoadMouseCursor(ImGuiMouseCursor.ResizeNWSE, Cursor.CursorType.SizeTopLeftBottomRight); LoadMouseCursor(ImGuiMouseCursor.Hand, Cursor.CursorType.Hand); if (loadDefaultFont) { // this will load default font automatically // No need to call AddDefaultFont UpdateFontTexture(); } _windowHasFocus = window.HasFocus(); window.MouseMoved += OnMouseMoved; window.MouseButtonPressed += OnMouseButtonPressed; window.MouseButtonReleased += OnMouseButtonReleased; window.TouchBegan += OnTouchBegan; window.TouchEnded += OnTouchEnded; window.MouseWheelScrolled += OnMouseWheelScrolled; window.KeyPressed += OnKeyPressed; window.KeyReleased += OnKeyReleased; window.TextEntered += OnTextEntered; window.JoystickConnected += OnJoystickConnected; window.JoystickDisconnected += OnJoystickDisconnected; window.GainedFocus += OnGainedFocus; window.LostFocus += OnLostFocus; }
public unsafe void Draw(string title, byte[] mem_data, int mem_size, int base_display_addr = 0) { if (!ImGui.BeginWindow(title)) { ImGui.EndWindow(); 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(StyleVar.FramePadding, new Vector2(0, 0)); ImGui.PushStyleVar(StyleVar.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.GetTextSize("F").X; float cell_width = glyph_width * 3; // "FF " we include trailing space in the width to easily catch clicks everywhere var clipper = new ImGuiListClipper(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(GuiKey.UpArrow)) && DataEditingAddr >= Rows) { DataEditingAddr -= Rows; DataEditingTakeFocus = true; } else if (ImGui.IsKeyPressed(ImGui.GetKeyIndex(GuiKey.DownArrow)) && DataEditingAddr < mem_size - Rows) { DataEditingAddr += Rows; DataEditingTakeFocus = true; } else if (ImGui.IsKeyPressed(ImGui.GetKeyIndex(GuiKey.LeftArrow)) && DataEditingAddr > 0) { DataEditingAddr -= 1; DataEditingTakeFocus = true; } else if (ImGui.IsKeyPressed(ImGui.GetKeyIndex(GuiKey.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.igSetScrollY(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. TextEditCallback callback = (data) => { int *p_cursor_pos = (int *)data->UserData; if (!data->HasSelection()) { *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.GetTextSize("FF").X); var flags = InputTextFlags.CharsHexadecimal | InputTextFlags.EnterReturnsTrue | InputTextFlags.AutoSelectAll | InputTextFlags.NoHorizontalScroll | InputTextFlags.AlwaysInsertMode | InputTextFlags.CallbackAlways; if (ImGui.InputText("##data", DataInput, 32, flags, callback, new IntPtr(&cursor_pos))) { data_write = data_next = true; } else if (!DataEditingTakeFocus && !ImGui.IsLastItemActive()) { 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(HoveredFlags.Default) && 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); ImGuiNative.igPushAllowKeyboardFocus(false); 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); } ImGuiNative.igPopAllowKeyboardFocus(); 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, InputTextFlags.CharsHexadecimal | InputTextFlags.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"); ImGuiNative.igSetScrollFromPosY(ImGui.GetCursorStartPos().Y + (goto_addr / Rows) * ImGuiNative.igGetTextLineHeight()); ImGui.EndChild(); DataEditingAddr = goto_addr; DataEditingTakeFocus = true; } } } ImGui.PopItemWidth(); ImGui.EndWindow(); }
public static void Render() { if (!WindowManager.LootTable) { return; } ImGui.SetNextWindowSize(size, ImGuiCond.Once); if (!ImGui.Begin("Loot Table Editor")) { ImGui.End(); return; } if (ImGui.Button("Save")) { LootTables.Save(); } ImGui.SameLine(); if (ImGui.Button("New##pe")) { ImGui.OpenPopup("Add Item##pe"); } if (selectedTable != null) { ImGui.SameLine(); if (ImGui.Button("Delete")) { LootTables.Defined.Remove(selectedTable); LootTables.Data.Remove(selectedTable); selectedTable = null; } } filter.Draw(""); ImGui.SameLine(); ImGui.Text($"{count}"); if (ImGui.BeginPopupModal("Add Item##pe")) { ImGui.PushItemWidth(300); ImGui.InputText("Id", ref poolName, 64); ImGui.PopItemWidth(); if (ImGui.Button("Add") || Input.Keyboard.WasPressed(Keys.Enter, true)) { selectedTable = poolName; LootTables.Defined[poolName] = new AnyDrop(); LootTables.Data[poolName] = new JsonObject { ["type"] = "any" }; poolName = ""; ImGui.CloseCurrentPopup(); } ImGui.SameLine(); if (ImGui.Button("Cancel") || Input.Keyboard.WasPressed(Keys.Escape, true)) { poolName = ""; ImGui.CloseCurrentPopup(); } ImGui.EndPopup(); } if (selectedTable != null) { ImGui.SameLine(); if (ImGui.Button("Remove##pe")) { LootTables.Defined.Remove(selectedTable); selectedTable = null; } } count = 0; ImGui.Separator(); var height = ImGui.GetStyle().ItemSpacing.Y; ImGui.BeginChild("rolingRegionItems##Pe", new System.Numerics.Vector2(0, -height), false, ImGuiWindowFlags.HorizontalScrollbar); foreach (var i in LootTables.Defined) { ImGui.PushID($"{id}___m"); if (filter.PassFilter(i.Key)) { count++; if (ImGui.Selectable($"{i.Key}##ped", i.Key == selectedTable)) { selectedTable = i.Key; } } ImGui.PopID(); id++; } id = 0; ImGui.EndChild(); ImGui.End(); if (selectedTable == null) { return; } var show = true; ImGui.SetNextWindowSize(size, ImGuiCond.Once); if (!ImGui.Begin("Loot Table", ref show)) { ImGui.End(); return; } if (!show) { selectedTable = null; ImGui.End(); return; } LootTables.RenderDrop(LootTables.Data[selectedTable]); ImGui.End(); }