public static bool DragDropSource(string name, ushort handleIdx, DragDropWindow window, DragDropTree tree, string payloadType, ImGuiDragDropFlags flags) { if (ImGui.BeginDragDropSource(flags)) { s_dragdropDataD[0] = (byte)window; s_dragdropDataD[1] = (byte)tree; Util.GetBytesGC0(handleIdx, ref s_tmpBytesForShort); Array.Copy(s_tmpBytesForShort, 0, s_dragdropDataD, 2, 2); IntPtr dataPtr; unsafe { fixed(byte *native = &s_dragdropDataD[0]) { dataPtr = (IntPtr)(native); } } ImGui.SetDragDropPayload(payloadType, dataPtr, s_dragdrop_size); ImGui.Text(name); ImGui.EndDragDropSource(); return(true); } return(false); }
void Traverse(GameObject gameObject) { bool leaf = gameObject.Transform.Children.Count <= 0; if (gameObject == selectedObj) { ImGui.PushStyleColor(ImGuiCol.Text, new System.Numerics.Vector4(0.25882352941f, 0.5294117647f, 0.96078431372f, 1)); } var x = ImGui.GetCursorPosX(); ImGui.Dummy(new System.Numerics.Vector2(ImGui.GetContentRegionAvail().X, ImGui.GetFontSize())); ImGui.SameLine(); ImGui.SetCursorPosX(x); bool open = ImGui.TreeNodeEx(gameObject.UIDText, (!ImGui.IsMouseClicked(ImGuiMouseButton.Left) && leaf ? ImGuiTreeNodeFlags.Leaf : 0) | ImGuiTreeNodeFlags.OpenOnDoubleClick | ImGuiTreeNodeFlags.SpanAvailWidth | ImGuiTreeNodeFlags.OpenOnArrow, gameObject.Name); if (ImGui.BeginDragDropSource()) { if (ImGui.SetDragDropPayload("Transform", IntPtr.Zero, 0)) { scr = gameObject.Transform; } ImGui.EndDragDropSource(); } if (ImGui.BeginDragDropTarget()) { var payload = ImGui.AcceptDragDropPayload("Transform"); if (payload.NativePtr != null && scr != null) { scr.Parent = gameObject.Transform; } ImGui.EndDragDropTarget(); } if (gameObject == selectedObj) { ImGui.PopStyleColor(); } if (ImGui.IsItemClicked()) { if (selectedObj != gameObject) { SelectionChanged(gameObject); } selectedObj = gameObject; } if (open) { for (int i = 0; i < gameObject.Transform.Children.Count; i++) { Traverse(gameObject.Transform.Children[i].GameObject); } ImGui.TreePop(); } }
private static bool DrawDragDropTargetSources(CooldownTrigger trigger, IList <int> toSwap) { const string payloadIdentifier = "PRIORITY_PAYLOAD"; if (ImGui.BeginDragDropSource(ImGuiDragDropFlags.SourceNoHoldToOpenOthers | ImGuiDragDropFlags.SourceNoPreviewTooltip)) { unsafe { var prio = trigger.Priority; var ptr = new IntPtr(&prio); ImGui.SetDragDropPayload(payloadIdentifier, ptr, sizeof(int)); } ImGui.SameLine(); ImGui.AlignTextToFramePadding(); #if DEBUG ImGui.Text($"{trigger.Priority + 1} Dragging {trigger.ActionName}."); #else ImGui.Text($"Dragging {trigger.ActionName}."); #endif ImGui.EndDragDropSource(); return(true); } if (!ImGui.BeginDragDropTarget()) { return(false); } var imGuiPayloadPtr = ImGui.AcceptDragDropPayload(payloadIdentifier, ImGuiDragDropFlags.AcceptNoPreviewTooltip | ImGuiDragDropFlags.AcceptNoDrawDefaultRect); unsafe { if (imGuiPayloadPtr.NativePtr is not null) { var prio = *(int *)imGuiPayloadPtr.Data; toSwap[0] = prio; toSwap[1] = trigger.Priority; } } ImGui.SameLine(); ImGui.AlignTextToFramePadding(); #if DEBUG ImGui.Text($"{trigger.Priority + 1} Swap with {trigger.ActionName}"); #else ImGui.Text($"Swap with {trigger.ActionName}"); #endif ImGui.EndDragDropTarget(); return(true); }
protected virtual unsafe void DragVarProc(T tObj, out bool onEvent) { onEvent = false; dragVarID = tObj.ID; fixed(int *p = &dragVarID) { System.IntPtr intPtr = new System.IntPtr(p); if (ImGui.BeginDragDropSource(ImGuiDragDropFlags.None)) { // Set payload to carry the index of our item (could be anything) ImGui.SetDragDropPayload(GetPayloadType(), intPtr, sizeof(int)); // Display preview (could be anything, e.g. when dragging an image we could decide to display // the filename and a small preview of the image, etc.) ImGui.Text(tObj.Name + ":" + dragVarID); ImGui.EndDragDropSource(); } } }
private void TreeRecursive(GameObject GO, bool Root) { if (GO.ShouldBeDeleted || GO.IsEditor) { return; } int ChildrenCount = GO.Children.Count; if (ChildrenCount == 0) { if (!Root) { ImGui.Indent(); } if (!GO.IsActive()) { ImGui.PushStyleColor(ImGuiCol.Text, new Vector4(0.5f, 0.5f, 0.5f, 1)); ImGui.PushStyleColor(ImGuiCol.HeaderHovered, new Vector4(0.8f, 0.8f, 0.8f, 1)); } ImGui.Selectable(GO.Name, SelectedGOs.Contains(GO)); if (ImGui.IsMouseDoubleClicked(ImGuiMouseButton.Left)) { if (ImGui.IsItemClicked()) { Setup.Camera.Position = GO.Transform.Position + new Microsoft.Xna.Framework.Vector2(-GizmosVisualizer.SceneWindow.Z * 0.5f + Setup.graphics.PreferredBackBufferWidth * 0.5f, -GizmosVisualizer.SceneWindow.W * 0.5f + Setup.graphics.PreferredBackBufferHeight * 0.5f); } } //Accept Drag and Drop if (ImGui.BeginDragDropSource(ImGuiDragDropFlags.SourceNoDisableHover)) { ImGui.SetDragDropPayload("GameObject", IntPtr.Zero, 0); DraggedGO = GO; InspectorWindow.DraggedObject = GO; ImGui.Text(GO.Name); ImGui.EndDragDropSource(); } // The GameObject is a drag source and drop target at the same time if (ImGui.BeginDragDropTarget()) { if (ImGui.IsMouseReleased(ImGuiMouseButton.Left)) { if (DraggedGO != null && GO.Parent != DraggedGO) { if (DraggedGO.Parent != null) { DraggedGO.Parent.RemoveChild(DraggedGO); } GO.AddChild(DraggedGO); // Undo and Redo Buffering KeyValuePair <object, GameObject> KVP_GO = new KeyValuePair <object, GameObject>(new KeyValuePair <GameObject, string>(DraggedGO, (DraggedGO.Parent == null) ? null : DraggedGO.Parent.Name), GO); AddToACircularBuffer(Undo_Buffer, new KeyValuePair <object, Operation>(KVP_GO, Operation.GO_DragAndDrop)); Redo_Buffer.Clear(); } DraggedGO = null; } ImGui.EndDragDropTarget(); } if (!GO.IsActive()) { ImGui.PopStyleColor(); ImGui.PopStyleColor(); } if (!Root) { ImGui.Unindent(); } if (ImGui.IsMouseReleased(ImGuiMouseButton.Left) && ImGui.IsItemHovered()) { if (ImGui.GetIO().KeyCtrl) { if (!SelectedGOs.Add(GO)) { SelectedGOs.Remove(GO); } else { WhoIsSelected = GO; } } else if (ImGui.GetIO().KeyShift) { if (SelectedGOs.Count == 0) { SelectedGOs.Add(GO); WhoIsSelected = GO; } else { SelectedGOs.Clear(); int CurrentGoIndex = -1; int LastOneIndex = -1; for (int i = 0; i < SceneManager.ActiveScene.GameObjects.Count; i++) { if (SceneManager.ActiveScene.GameObjects[i] == GO) { CurrentGoIndex = i; } if (SceneManager.ActiveScene.GameObjects[i] == WhoIsSelected) { LastOneIndex = i; } } WhoIsSelected = GO; if (CurrentGoIndex > LastOneIndex) { for (int i = LastOneIndex; i <= CurrentGoIndex; i++) { SelectedGOs.Add(SceneManager.ActiveScene.GameObjects[i]); } } else { for (int i = CurrentGoIndex; i <= LastOneIndex; i++) { SelectedGOs.Add(SceneManager.ActiveScene.GameObjects[i]); } } } } else { SelectedGOs.Clear(); if (!SelectedGOs.Add(GO)) { SelectedGOs.Remove(GO); } else { WhoIsSelected = GO; } } } return; } if (Root) { ImGui.Unindent(); } bool Open = ImGui.TreeNodeEx(GO.Name, SelectedGOs.Contains(GO) ? ImGuiTreeNodeFlags.Selected : ImGuiTreeNodeFlags.None); if (!GO.IsActive()) { ImGui.PushStyleColor(ImGuiCol.Text, new Vector4(0.5f, 0.5f, 0.5f, 1)); ImGui.PushStyleColor(ImGuiCol.HeaderHovered, new Vector4(0.8f, 0.8f, 0.8f, 1)); } if (ImGui.IsMouseDoubleClicked(ImGuiMouseButton.Left)) { if (ImGui.IsItemClicked()) { Setup.Camera.Position = GO.Transform.Position + (MyRegion[1].X + MyRegion[0].X) * Microsoft.Xna.Framework.Vector2.UnitX; } } //Accept Drag and Drop if (ImGui.BeginDragDropSource(ImGuiDragDropFlags.SourceNoDisableHover)) { ImGui.SetDragDropPayload("GameObject", IntPtr.Zero, 0); DraggedGO = GO; InspectorWindow.DraggedObject = GO; ImGui.Text(GO.Name); ImGui.EndDragDropSource(); } // The GameObject is a drag source and drop targer at the same time if (ImGui.BeginDragDropTarget()) { if (ImGui.IsMouseReleased(ImGuiMouseButton.Left)) { if (DraggedGO != null && GO.Parent != DraggedGO) { if (DraggedGO.Parent != null) { DraggedGO.Parent.RemoveChild(DraggedGO); } GO.AddChild(DraggedGO); // Undo and Redo Buffering KeyValuePair <object, GameObject> KVP_GO = new KeyValuePair <object, GameObject>(new KeyValuePair <GameObject, string>(DraggedGO, (DraggedGO.Parent == null) ? null : DraggedGO.Parent.Name), GO); AddToACircularBuffer(Undo_Buffer, new KeyValuePair <object, Operation>(KVP_GO, Operation.GO_DragAndDrop)); Redo_Buffer.Clear(); } DraggedGO = null; } ImGui.EndDragDropTarget(); } if (!GO.IsActive()) { ImGui.PopStyleColor(); ImGui.PopStyleColor(); } if (ImGui.IsMouseReleased(ImGuiMouseButton.Left) && ImGui.IsItemHovered()) { if (ImGui.GetIO().KeyCtrl) { if (!SelectedGOs.Add(GO)) { SelectedGOs.Remove(GO); } if (SelectedGOs.Count != 0) { WhoIsSelected = GO; } } else if (ImGui.GetIO().KeyShift) { if (SelectedGOs.Count == 0) { SelectedGOs.Add(GO); WhoIsSelected = GO; } else { SelectedGOs.Clear(); int CurrentGoIndex = -1; int LastOneIndex = -1; for (int i = 0; i < SceneManager.ActiveScene.GameObjects.Count; i++) { if (SceneManager.ActiveScene.GameObjects[i] == GO) { CurrentGoIndex = i; } if (SceneManager.ActiveScene.GameObjects[i] == WhoIsSelected) { LastOneIndex = i; } } WhoIsSelected = GO; if (CurrentGoIndex > LastOneIndex) { for (int i = LastOneIndex; i <= CurrentGoIndex; i++) { SelectedGOs.Add(SceneManager.ActiveScene.GameObjects[i]); } } else { for (int i = CurrentGoIndex; i <= LastOneIndex; i++) { SelectedGOs.Add(SceneManager.ActiveScene.GameObjects[i]); } } } } else { SelectedGOs.Clear(); if (!SelectedGOs.Add(GO)) { SelectedGOs.Remove(GO); } else { WhoIsSelected = GO; } } } for (int i = 0; i < ChildrenCount; i++) { if (ChildrenCount != GO.Children.Count) { break; } if (Open) { TreeRecursive(GO.Children[i], false); } } if (Open) { ImGui.TreePop(); } if (Root) { ImGui.Indent(); } }
public void DrawNode(NodeBase node, float itemHeight) { bool HasText = node.Header != null && node.Header.IndexOf(_searchText, StringComparison.OrdinalIgnoreCase) >= 0; char icon = IconManager.FOLDER_ICON; if (node.Children.Count == 0) { icon = IconManager.FILE_ICON; } if (node.Tag is STGenericMesh) { icon = IconManager.MESH_ICON; } if (node.Tag is STGenericModel) { icon = IconManager.MODEL_ICON; } ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags.None; flags |= ImGuiTreeNodeFlags.SpanFullWidth; if (node.Children.Count == 0 || isSearch) { flags |= ImGuiTreeNodeFlags.Leaf; } else { flags |= ImGuiTreeNodeFlags.OpenOnDoubleClick; flags |= ImGuiTreeNodeFlags.OpenOnArrow; } if (node.IsExpanded && !isSearch) { flags |= ImGuiTreeNodeFlags.DefaultOpen; } //Node was selected manually outside the outliner so update the list if (node.IsSelected && !SelectedNodes.Contains(node)) { SelectedNodes.Add(node); } //Node was deselected manually outside the outliner so update the list if (!node.IsSelected && SelectedNodes.Contains(node)) { SelectedNodes.Remove(node); } if (SelectedNodes.Contains(node)) { flags |= ImGuiTreeNodeFlags.Selected; } if (isSearch && HasText || !isSearch) { //Add active file format styling. This determines what file to save. //For files inside archives, it gets the parent of the file format to save. bool isActiveFile = false; isActiveFile = ActiveFileFormat == node.Tag; bool isRenaming = node == renameNode && isNameEditing && node.Tag is IRenamableNode; //Improve tree node spacing. var spacing = ImGui.GetStyle().ItemSpacing; ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, new Vector2(spacing.X, 1)); //Make the active file noticable if (isActiveFile) { ImGui.PushStyleColor(ImGuiCol.Text, new Vector4(0.834f, 0.941f, 1.000f, 1.000f)); } //Align the text to improve selection sizing. ImGui.AlignTextToFramePadding(); //Disable selection view in renaming handler to make text more clear if (isRenaming) { flags &= ~ImGuiTreeNodeFlags.Selected; flags &= ~ImGuiTreeNodeFlags.SpanFullWidth; } //Load the expander or selection if (isSearch) { ImGui.Selectable(node.ID, flags.HasFlag(ImGuiTreeNodeFlags.Selected)); } else { node.IsExpanded = ImGui.TreeNodeEx(node.ID, flags, $""); } ImGui.SameLine(); ImGuiHelper.IncrementCursorPosX(3); bool leftClicked = ImGui.IsItemClicked(ImGuiMouseButton.Left); bool rightClicked = ImGui.IsItemClicked(ImGuiMouseButton.Right); bool nodeFocused = ImGui.IsItemFocused(); bool isToggleOpened = ImGui.IsItemToggledOpen(); bool beginDragDropSource = !isRenaming && node.Tag is IDragDropNode && ImGui.BeginDragDropSource(); if (beginDragDropSource) { //Placeholder pointer data. Instead use drag/drop nodes from GetDragDropNode() GCHandle handle1 = GCHandle.Alloc(node.ID); ImGui.SetDragDropPayload("OUTLINER_ITEM", (IntPtr)handle1, sizeof(int), ImGuiCond.Once); handle1.Free(); dragDroppedNode = node; //Display icon for texture types if (node.Tag is STGenericTexture) { LoadTextureIcon(node); } //Display text for item being dragged ImGui.Button($"{node.Header}"); ImGui.EndDragDropSource(); } bool hasContextMenu = node is IContextMenu || node is IExportReplaceNode || node.Tag is ICheckableNode || node.Tag is IContextMenu || node.Tag is IExportReplaceNode || node.Tag is STGenericTexture; //Apply a pop up menu for context items. Only do this if the menu has possible items used if (hasContextMenu && SelectedNodes.Contains(node)) { ImGui.PushID(node.Header); if (ImGui.BeginPopupContextItem("##OUTLINER_POPUP", ImGuiPopupFlags.MouseButtonRight)) { SetupRightClickMenu(node); ImGui.EndPopup(); } ImGui.PopID(); } if (node.HasCheckBox) { ImGui.SetItemAllowOverlap(); ImGui.PushStyleVar(ImGuiStyleVar.FramePadding, new Vector2(2, 2)); bool check = node.IsChecked; if (ImGui.Checkbox($"##check{node.ID}", ref check)) { foreach (var n in SelectedNodes) { n.IsChecked = check; } } ImGui.PopStyleVar(); ImGui.SameLine(); ImGuiHelper.IncrementCursorPosX(3); } //Load the icon if (node.Tag is STGenericTexture) { LoadTextureIcon(node); } else { IconManager.DrawIcon(icon); ImGui.SameLine(); ImGuiHelper.IncrementCursorPosX(3); } ImGui.AlignTextToFramePadding(); //if (node.Tag is ICheckableNode) // ImGuiHelper.IncrementCursorPosY(-2); if (!isRenaming) { ImGui.Text(node.Header); } else { var renamable = node.Tag as IRenamableNode; var bg = ImGui.GetStyle().Colors[(int)ImGuiCol.WindowBg]; //Make the textbox frame background blend with the tree background //This is so we don't see the highlight color and can see text clearly ImGui.PushStyleColor(ImGuiCol.FrameBg, bg); ImGui.PushStyleColor(ImGuiCol.Border, new Vector4(1, 1, 1, 1)); ImGui.PushStyleVar(ImGuiStyleVar.FrameBorderSize, 1); var length = ImGui.CalcTextSize(renameText).X + 20; ImGui.PushItemWidth(length); if (ImGui.InputText("##RENAME_NODE", ref renameText, 512, ImGuiInputTextFlags.EnterReturnsTrue | ImGuiInputTextFlags.CallbackCompletion | ImGuiInputTextFlags.CallbackHistory | ImGuiInputTextFlags.NoHorizontalScroll)) { renamable.Renamed(renameText); node.Header = renameText; isNameEditing = false; } if (!ImGui.IsItemHovered() && ImGui.IsMouseClicked(ImGuiMouseButton.Left)) { isNameEditing = false; } ImGui.PopItemWidth(); ImGui.PopStyleVar(); ImGui.PopStyleColor(2); } ImGui.PopStyleVar(); if (isActiveFile) { ImGui.PopStyleColor(); } if (!isRenaming) { //Check for rename selection on selected renamable node if (node.IsSelected && node.Tag is IRenamableNode && RENAME_ENABLE) { bool renameStarting = renameClickTime != 0; bool wasCancelled = false; //Mouse click before editing started cancels the event if (renameStarting && leftClicked) { renameClickTime = 0; renameStarting = false; wasCancelled = true; } //Check for delay if (renameStarting) { //Create a delay between actions. This can be cancelled out during a mouse click var diff = ImGui.GetTime() - renameClickTime; if (diff > RENAME_DELAY_TIME) { //Name edit executed. Setup data for renaming. isNameEditing = true; renameNode = node; renameText = ((IRenamableNode)node.Tag).GetRenameText(); //Reset the time renameClickTime = 0; } } //User has started a rename click. Start a time check if (leftClicked && renameClickTime == 0 && !wasCancelled) { //Do a small delay for the rename event renameClickTime = ImGui.GetTime(); } } //Click event executed on item if ((leftClicked || rightClicked) && !isToggleOpened) //Prevent selection change on toggle { //Reset all selection unless shift/control held down if (!ImGui.GetIO().KeyCtrl&& !ImGui.GetIO().KeyShift) { foreach (var n in SelectedNodes) { n.IsSelected = false; } SelectedNodes.Clear(); } //Check selection range if (ImGui.GetIO().KeyShift) { SelectedRangeIndex = node.DisplayIndex; SelectRange = true; } else { SelectedIndex = node.DisplayIndex; } //Add the clicked node to selection. SelectedNodes.Add(node); node.IsSelected = true; } else if (nodeFocused && !isToggleOpened && !node.IsSelected) { if (!ImGui.GetIO().KeyCtrl&& !ImGui.GetIO().KeyShift) { foreach (var n in SelectedNodes) { n.IsSelected = false; } SelectedNodes.Clear(); } //Add the clicked node to selection. SelectedNodes.Add(node); node.IsSelected = true; } if (leftClicked && node.IsSelected) { if (node is ArchiveHiearchy && node.Tag == null) { var archiveWrapper = (ArchiveHiearchy)node; archiveWrapper.OpenFileFormat(); archiveWrapper.IsExpanded = true; } } //Update the active file format when selected. (updates dockspace layout and file menus) if (node.Tag is IFileFormat && node.IsSelected) { if (ActiveFileFormat != node.Tag) { ActiveFileFormat = (IFileFormat)node.Tag; } } else if (node.IsSelected && node.Parent != null) { } } } if (isSearch || node.IsExpanded) { //Todo find a better alternative to clip parents //Clip only the last level if (ClipNodes && node.Children.Count > 0 && node.Children[0].Children.Count == 0) { var children = node.Children.ToList(); if (isSearch) { children = GetSearchableNodes(children); } var clipper = new ImGuiListClipper2(children.Count, itemHeight); clipper.ItemsCount = children.Count; for (int line_i = clipper.DisplayStart; line_i < clipper.DisplayEnd; line_i++) // display only visible items { DrawNode(children[line_i], itemHeight); } } else { foreach (var child in node.Children) { DrawNode(child, itemHeight); } } if (!isSearch) { ImGui.TreePop(); } } }
private void TextNodeDragDrop(ITextNode node) { if (node != plugin.Configuration.RootFolder && ImGui.BeginDragDropSource()) { DraggedNode = node; ImGui.Text(node.Name); ImGui.SetDragDropPayload("TextNodePayload", IntPtr.Zero, 0); ImGui.EndDragDropSource(); } if (ImGui.BeginDragDropTarget()) { var payload = ImGui.AcceptDragDropPayload("TextNodePayload"); bool nullPtr; unsafe { nullPtr = payload.NativePtr == null; } var targetNode = node; if (!nullPtr && payload.IsDelivery() && DraggedNode != null) { if (plugin.Configuration.TryFindParent(DraggedNode, out var draggedNodeParent)) { if (targetNode is TextFolderNode targetFolderNode) { AddTextNode.Add(new AddTextNodeOperation { Node = DraggedNode, ParentNode = targetFolderNode, Index = -1 }); RemoveTextNode.Add(new RemoveTextNodeOperation { Node = DraggedNode, ParentNode = draggedNodeParent }); } else { if (plugin.Configuration.TryFindParent(targetNode, out var targetNodeParent)) { var targetNodeIndex = targetNodeParent.Children.IndexOf(targetNode); if (targetNodeParent == draggedNodeParent) { var draggedNodeIndex = targetNodeParent.Children.IndexOf(DraggedNode); if (draggedNodeIndex < targetNodeIndex) { targetNodeIndex -= 1; } } AddTextNode.Add(new AddTextNodeOperation { Node = DraggedNode, ParentNode = targetNodeParent, Index = targetNodeIndex }); RemoveTextNode.Add(new RemoveTextNodeOperation { Node = DraggedNode, ParentNode = draggedNodeParent }); } else { throw new Exception($"Could not find parent of node \"{targetNode.Name}\""); } } } else { throw new Exception($"Could not find parent of node \"{DraggedNode.Name}\""); } DraggedNode = null; } ImGui.EndDragDropTarget(); } }
unsafe private void MapObjectSelectable(Entity e, bool visicon, bool hierarchial = false) { // Main selectable if (e is MapEntity me) { ImGui.PushID(me.Type.ToString() + e.Name); } else { ImGui.PushID(e.Name); } bool doSelect = false; if (_setNextFocus) { ImGui.SetItemDefaultFocus(); _setNextFocus = false; doSelect = true; } bool nodeopen = false; string padding = hierarchial ? " " : " "; if (hierarchial && e.Children.Count > 0) { var treeflags = ImGuiTreeNodeFlags.OpenOnArrow | ImGuiTreeNodeFlags.SpanAvailWidth; if (_selection.GetSelection().Contains(e)) { treeflags |= ImGuiTreeNodeFlags.Selected; } nodeopen = ImGui.TreeNodeEx(e.PrettyName, treeflags); if (ImGui.IsItemHovered() && ImGui.IsMouseDoubleClicked(0)) { if (e.RenderSceneMesh != null) { _viewport.FrameBox(e.RenderSceneMesh.GetBounds()); } } } else { if (ImGui.Selectable(padding + e.PrettyName, _selection.GetSelection().Contains(e), ImGuiSelectableFlags.AllowDoubleClick | ImGuiSelectableFlags.AllowItemOverlap)) { // If double clicked frame the selection in the viewport if (ImGui.IsMouseDoubleClicked(0)) { if (e.RenderSceneMesh != null) { _viewport.FrameBox(e.RenderSceneMesh.GetBounds()); } } } } if (ImGui.IsItemClicked(0)) { _pendingClick = e; } if (_pendingClick == e && ImGui.IsMouseReleased(ImGuiMouseButton.Left)) { if (ImGui.IsItemHovered()) { doSelect = true; } _pendingClick = null; } if (ImGui.IsItemFocused() && !_selection.IsSelected(e)) { doSelect = true; } if (hierarchial && doSelect) { if ((nodeopen && !_treeOpenEntities.Contains(e)) || (!nodeopen && _treeOpenEntities.Contains(e))) { doSelect = false; } if (nodeopen && !_treeOpenEntities.Contains(e)) { _treeOpenEntities.Add(e); } else if (!nodeopen && _treeOpenEntities.Contains(e)) { _treeOpenEntities.Remove(e); } } if (ImGui.BeginPopupContextItem()) { _handler.OnEntityContextMenu(e); ImGui.EndPopup(); } if (ImGui.BeginDragDropSource()) { ImGui.Text(e.PrettyName); // Kinda meme DragDropPayload p = new DragDropPayload(); p.Entity = e; _dragDropPayloads.Add(_dragDropPayloadCounter, p); DragDropPayloadReference r = new DragDropPayloadReference(); r.Index = _dragDropPayloadCounter; _dragDropPayloadCounter++; GCHandle handle = GCHandle.Alloc(r, GCHandleType.Pinned); ImGui.SetDragDropPayload("entity", handle.AddrOfPinnedObject(), (uint)sizeof(DragDropPayloadReference)); ImGui.EndDragDropSource(); handle.Free(); _initiatedDragDrop = true; } if (hierarchial && ImGui.BeginDragDropTarget()) { var payload = ImGui.AcceptDragDropPayload("entity"); if (payload.NativePtr != null) { DragDropPayloadReference *h = (DragDropPayloadReference *)payload.Data; var pload = _dragDropPayloads[h->Index]; _dragDropPayloads.Remove(h->Index); _dragDropSources.Add(pload.Entity); _dragDropDestObjects.Add(e); _dragDropDests.Add(e.Children.Count); } ImGui.EndDragDropTarget(); } // Visibility icon if (visicon) { ImGui.SetItemAllowOverlap(); bool visible = e.EditorVisible; ImGui.SameLine(ImGui.GetWindowContentRegionWidth() - 18.0f); ImGui.PushStyleColor(ImGuiCol.Text, visible ? new Vector4(1.0f, 1.0f, 1.0f, 1.0f) : new Vector4(0.6f, 0.6f, 0.6f, 1.0f)); ImGui.TextWrapped(visible ? ForkAwesome.Eye : ForkAwesome.EyeSlash); ImGui.PopStyleColor(); if (ImGui.IsItemClicked(0)) { e.EditorVisible = !e.EditorVisible; doSelect = false; } } // If the visibility icon wasn't clicked actually perform the selection if (doSelect) { if (InputTracker.GetKey(Key.ControlLeft) || InputTracker.GetKey(Key.ControlRight)) { _selection.AddSelection(e); } else { _selection.ClearSelection(); _selection.AddSelection(e); } } ImGui.PopID(); // Invisible item to be a drag drop target between nodes if (_pendingDragDrop) { if (e is MapEntity me2) { ImGui.SetItemAllowOverlap(); ImGui.InvisibleButton(me2.Type.ToString() + e.Name, new Vector2(-1, 3.0f)); } else { ImGui.SetItemAllowOverlap(); ImGui.InvisibleButton(e.Name, new Vector2(-1, 3.0f)); } if (ImGui.IsItemFocused()) { _setNextFocus = true; } if (ImGui.BeginDragDropTarget()) { var payload = ImGui.AcceptDragDropPayload("entity"); if (payload.NativePtr != null) { DragDropPayloadReference *h = (DragDropPayloadReference *)payload.Data; var pload = _dragDropPayloads[h->Index]; _dragDropPayloads.Remove(h->Index); if (hierarchial) { _dragDropSources.Add(pload.Entity); _dragDropDestObjects.Add(e.Parent); _dragDropDests.Add(e.Parent.ChildIndex(e) + 1); } else { _dragDropSources.Add(pload.Entity); _dragDropDests.Add(pload.Entity.Container.Objects.IndexOf(e) + 1); } } ImGui.EndDragDropTarget(); } } // If there's children then draw them if (nodeopen) { HierarchyView(e); ImGui.TreePop(); } }
private void DrawComponents(Entity context) { // TODO: fix bool entityEnabled = context.Enabled; if (ImGui.Checkbox("Enabled", ref entityEnabled)) { context.Enabled = entityEnabled; } var components = context.Components; for (int compi = 0; compi < components.Count; compi++) { Component component = components[compi]; Type componentType = component.GetType(); bool stay = true; ImGui.PushID(componentType.Name + compi); bool valcol = !component.Valid; if (valcol) { ImGui.PushStyleColor(ImGuiCol.Header, new Vector4(0.412f, 0.118f, 0.118f, 1.0f)); ImGui.PushStyleColor(ImGuiCol.HeaderHovered, new Vector4(0.729f, 0.208f, 0.208f, 1.0f)); } // item shifting drop unsafe { // smoll fix bool resetTarget = false; if (targetedComponent == component) { ImGui.Button("##target", new Vector2(ImGui.GetColumnWidth(), 2.5f)); if (ImGui.IsItemHovered()) { resetTarget = true; } } if (ImGui.BeginDragDropTarget()) { var payload = ImGui.AcceptDragDropPayload("_COMPONENT"); if (payload.NativePtr != null && selectedDragNDropComponent != null) { int tci = Context.ActiveEntity.GetComponentIndex(targetedComponent); if (tci > Context.ActiveEntity.GetComponentIndex(selectedDragNDropComponent)) { tci--; } Context.ActiveEntity.ShiftComponent(selectedDragNDropComponent, tci); selectedDragNDropComponent = null; targetedComponent = null; } ImGui.EndDragDropTarget(); } if (resetTarget) { targetedComponent = null; } } bool collapsingHeader = ImGui.CollapsingHeader(componentType.Name, ref stay); // item shifting drag { if (ImGui.BeginDragDropSource()) { ImGui.Text("Component: " + componentType.Name); selectedDragNDropComponent = component; ImGui.SetDragDropPayload("_COMPONENT", IntPtr.Zero, 0); ImGui.EndDragDropSource(); } if (ImGui.BeginDragDropTarget()) { targetedComponent = component; ImGui.EndDragDropTarget(); } } // contex menu { if (ImGui.BeginPopupContextItem()) { if (ImGui.MenuItem("Move Up")) { context.ShiftComponent(component, Math.Max(0, compi - 1)); } if (ImGui.MenuItem("Move Down")) { context.ShiftComponent(component, Math.Min(components.Count - 1, compi + 1)); } ImGui.Separator(); if (ImGui.MenuItem("Remove")) { Context.ActiveEntity.RemoveComponent(component); } ImGui.EndPopup(); } } var style = ImGui.GetStyle(); float collapsingHeaderButtonOffset = ((ImGui.GetTextLineHeight() + style.FramePadding.Y * 2) + 1); ImGui.SameLine(ImGui.GetContentRegionAvail().X - (collapsingHeaderButtonOffset * 1 + style.FramePadding.X + style.FramePadding.Y)); bool enabled = component.Enabled; if (ImGui.Checkbox("##enabled", ref enabled)) { component.Enabled = enabled; } ImGui.SameLine(ImGui.GetContentRegionAvail().X - (collapsingHeaderButtonOffset * 2 + style.FramePadding.X + style.FramePadding.Y)); if (ImGui.ArrowButton("up", ImGuiDir.Up)) { context.ShiftComponent(component, Math.Max(0, compi - 1)); } ImGui.SameLine(ImGui.GetContentRegionAvail().X - (collapsingHeaderButtonOffset * 3 + style.FramePadding.X + style.FramePadding.Y)); if (ImGui.ArrowButton("down", ImGuiDir.Down)) { context.ShiftComponent(component, Math.Min(components.Count - 1, compi + 1)); } if (collapsingHeader) { ImGuiUtils.BeginGroupFrame(); MemberInfo[] membs = componentType.GetMembers(); for (int mi = 0; mi < membs.Length; mi++) { var mem = membs[mi]; if (mem.MemberType == MemberTypes.Field || mem.MemberType == MemberTypes.Property) { PropertyDrawer.DrawEditorValue(mem, component); } } //ImGui.Separator(); ImGuiUtils.EndGroupFrame(); } if (valcol) { ImGui.PopStyleColor(2); } ImGui.PopID(); if (!stay) { Context.ActiveEntity.RemoveComponent(component); } } }
public static bool BeginDragDropSource(ImGuiDragDropFlags flags) { return(ImGui.BeginDragDropSource(flags)); }
void DrawEntityNode(TreeNode <Entity> node, string id, int i = 0) { Entity nodeEntity = node.Value; // drag drop unsafe { // smoll fix bool resetTarget = false; if (targetedNode == node && targetedNode.Value != null) { ImGui.Button("##target", new Vector2(ImGui.GetColumnWidth(), 2.5f)); if (ImGui.IsItemHovered()) { resetTarget = true; } } // dropped next to if (ImGui.BeginDragDropTarget()) { var payload = ImGui.AcceptDragDropPayload("_TREENODE<ENTITY>"); if (payload.NativePtr != null && selectedDragNDropNode != null) { EditorApplication.Log.Trace("dropped " + $"{((selectedDragNDropNode != null && selectedDragNDropNode.Value != null) ? selectedDragNDropNode.Value.UID : "null")} before " + $"{((targetedNode != null && nodeEntity != null) ? nodeEntity.UID : "null")}"); if (!targetedNode.IsParentedBy(selectedDragNDropNode)) { if (selectedDragNDropNode.Parent != targetedNode.Parent) { selectedDragNDropNode.Value.Parent = targetedNode.Value.Parent; } int tnei = Context.Scene.GetEntityIndex(targetedNode.Value); if (tnei > Context.Scene.GetEntityIndex(selectedDragNDropNode.Value)) { tnei--; } Context.Scene.ShiftEntity(selectedDragNDropNode.Value, tnei); int tnci = targetedNode.Parent.GetChildIndex(targetedNode); if (tnci > targetedNode.Parent.GetChildIndex(selectedDragNDropNode)) { tnci--; } targetedNode.Parent.ShiftChild(selectedDragNDropNode, tnci); } else { EditorApplication.Log.Trace($"drop failed (cyclic tree prevented)"); } selectedDragNDropNode = null; targetedNode = null; } ImGui.EndDragDropTarget(); } if (resetTarget) { targetedNode = null; } } ImGuiTreeNodeFlags flags = ((nodeEntity == Context.ActiveEntity) ? ImGuiTreeNodeFlags.Selected : ImGuiTreeNodeFlags.None) | ImGuiTreeNodeFlags.OpenOnArrow | ImGuiTreeNodeFlags.OpenOnDoubleClick | ImGuiTreeNodeFlags.DefaultOpen | ((node.Children.Count <= 0) ? ImGuiTreeNodeFlags.Leaf : ImGuiTreeNodeFlags.None); if (nodeEntity == Context.ActiveEntity) { ImGui.PushStyleColor(ImGuiCol.Text, new Vector4(0.259f, 0.588f, 0.98f, 1.0f)); } string label = (Context.Scene.HierarchyRoot == node) ? "Scene" : (nodeEntity != null) ? ( nodeEntity.TryGetComponent(out TagComponent tagcomp) ? tagcomp.Tag : "uid: " + nodeEntity.UID.ToString()) : ""; bool opened = ImGui.TreeNodeEx(id + i.ToString(), flags, label); if (nodeEntity == Context.ActiveEntity) { ImGui.PopStyleColor(); } if (ImGui.IsItemClicked()) { Context.ActiveEntity = nodeEntity; } // drag drop unsafe { if (ImGui.BeginDragDropSource()) { ImGui.Text("Entity: " + label); selectedDragNDropNode = node; ImGui.SetDragDropPayload("_TREENODE<ENTITY>", IntPtr.Zero, 0); ImGui.EndDragDropSource(); } // dropped on to if (ImGui.BeginDragDropTarget()) { targetedNode = node; var payload = ImGui.AcceptDragDropPayload("_TREENODE<ENTITY>"); if (payload.NativePtr != null) { EditorApplication.Log.Trace("dropped " + $"{((selectedDragNDropNode != null && selectedDragNDropNode.Value != null) ? selectedDragNDropNode.Value.UID : "null")} onto " + $"{((node != null && nodeEntity != null) ? nodeEntity.UID : "null")}"); if (!node.IsParentedBy(selectedDragNDropNode)) { selectedDragNDropNode.Value.Parent = nodeEntity; } else { EditorApplication.Log.Trace($"drop failed (cyclic tree prevented)"); } selectedDragNDropNode = null; targetedNode = null; } ImGui.EndDragDropTarget(); } } // context menu { if (ImGui.BeginPopupContextItem()) { if (ImGui.MenuItem("Add child")) { var newboi = Context.Scene.CreateEntity(); newboi.Parent = nodeEntity; } if (ImGui.MenuItem("Add empty child")) { var newboi = Context.Scene.CreateEmptyEntity(); newboi.Parent = nodeEntity; } ImGui.Separator(); if (ImGui.MenuItem("Remove entity", nodeEntity != null)) { Context.Scene.DestroyEntity(nodeEntity); Context.ActiveEntity = null; } ImGui.EndPopup(); } } if (opened) { for (int cni = 0; cni < node.Children.Count; cni++) { DrawEntityNode(node.Children[cni], id + "|" + i++.ToString()); } ImGui.TreePop(); } }
public static void BeginDragDropSource(GUIDragDropFlags flags) => ImGui.BeginDragDropSource((ImGuiDragDropFlags)flags);
public static bool BeginDragDropSource() => ImGui.BeginDragDropSource();
public static int DragAndDropList <T>(T[] list, int draggedState, bool horizontal = false) { //draggedState = -1; for (var i = 0; i < list.Length; i++) { T item = list[i]; if (item == null) { continue; } if (i == draggedState) { ImGui.PushStyleColor(ImGuiCol.Button, 0); ImGui.PushStyleColor(ImGuiCol.Text, 0); } ImGui.PushID($"Item {i}"); ImGui.Button(item.ToString()); ImGui.PopID(); if (i == draggedState) { ImGui.PopStyleColor(); ImGui.PopStyleColor(); } if (ImGui.BeginDragDropSource()) { draggedState = i; ImGui.PushID("carrying"); ImGui.Text(item.ToString()); ImGui.PopID(); ImGui.SetDragDropPayload("UNUSED", IntPtr.Zero, 0); ImGui.EndDragDropSource(); } if (ImGui.BeginDragDropTarget()) { ImGuiPayloadPtr dataPtr = ImGui.AcceptDragDropPayload("UNUSED"); unsafe { if ((IntPtr)dataPtr.NativePtr != IntPtr.Zero && dataPtr.IsDelivery()) { int idxDragged = draggedState; (list[idxDragged], list[i]) = (list[i], list[idxDragged]); draggedState = -1; } } ImGui.EndDragDropTarget(); } // Check if drag/drop ended. ImGuiPayloadPtr payLoad = ImGui.GetDragDropPayload(); unsafe { if ((IntPtr)payLoad.NativePtr == IntPtr.Zero) { draggedState = -1; } } if (horizontal && i != list.Length - 1) { ImGui.SameLine(); } } return(draggedState); }
private static unsafe void AddSceneGraphTransforms(EntityAdmin admin, List <Transform> list) { // The selectedTransform is either the selectedEntityComponent (if it's a Transform) or the Transform associated with the selected Entity/Component. Transform selectedTransform = SelectedEntityComponent as Transform; if (selectedTransform == null) { Entity entity = SelectedEntityComponent as Entity; if (entity == null) { Component component = SelectedEntityComponent as Component; if (component != null) { entity = component.Entity; } } if (entity != null) { selectedTransform = entity.GetComponent <Transform>(true); } } foreach (var transform in list) { ImGuiTreeNodeFlags nodeFlags = ImGuiTreeNodeFlags.OpenOnArrow | ImGuiTreeNodeFlags.OpenOnDoubleClick | ImGuiTreeNodeFlags.SpanAvailWidth; // OpenOnDoubleClick doesn't seem to work. Not sure why. if (transform.Children.Count == 0) { nodeFlags |= ImGuiTreeNodeFlags.Leaf; } if (transform == selectedTransform) { nodeFlags |= ImGuiTreeNodeFlags.Selected; if (scrollSceneGraphView) { ImGui.SetScrollHereY(); } } bool parentOfSelected = false; Transform parent = selectedTransform as Transform; while (parent != null) { parent = parent.Parent; if (parent == transform) { parentOfSelected = true; break; } } if (parentOfSelected) { ImGui.SetNextItemOpen(true); } if (!transform.IsActive) { ImGui.PushStyleColor(ImGuiCol.Text, new Vector4(0.5f, 0.5f, 0.5f, 1f)); } bool expanded = ImGui.TreeNodeEx(transform.Guid.ToString(), nodeFlags, transform.EntityName); if (!transform.IsActive) { ImGui.PopStyleColor(); } if (ImGui.IsItemClicked()) { SelectedEntityComponent = transform; scrollEntitiesView = true; } if (ImGui.BeginDragDropSource()) { ImGui.SetDragDropPayload(PAYLOAD_STRING, IntPtr.Zero, 0); // Payload is needed to trigger BeginDragDropTarget() draggedObject = transform; ImGui.Text(transform.EntityName); ImGui.EndDragDropSource(); } if (draggedObject != null && draggedObject is Transform) { if (ImGui.BeginDragDropTarget()) { var payload = ImGui.AcceptDragDropPayload(PAYLOAD_STRING); if (payload.NativePtr != null) // Only when this is non-null does it mean that we've released the drag { Transform draggedTransform = draggedObject as Transform; Transform newParent; if (draggedTransform.Parent == transform) { newParent = null; } else { newParent = transform; } Transform.AssignParent(draggedTransform, newParent, admin, true); draggedObject = null; } ImGui.EndDragDropTarget(); } } if (expanded) { AddSceneGraphTransforms(admin, transform.Children.ToList()); ImGui.TreePop(); } } }
public override void DrawUI() { if (IsWindowOpen) { if (ImGui.IsKeyPressed(ImGui.GetKeyIndex(ImGuiKey.Escape))) { IsWindowOpen = false; } ImGui.PushStyleVar(ImGuiStyleVar.Alpha, 2); ImGui.PushStyleColor(ImGuiCol.Button, new Vector4(0.4f, 0.4f, 0.4f, 1)); ImGui.Begin("Animation Editor"); if (ImGui.Button("New Animation")) { string[] ClipNames = new string[AnimationClips.Count]; for (int i = 0; i < AnimationClips.Count; i++) { ClipNames[i] = AnimationClips[i].Name; } AnimationClips.Add(new AnimationInfo() { Frames = new List <Frame>(), Name = Utility.UniqueName("Default Animation", ClipNames) }); SelectedClip = AnimationClips.Count - 1; SearchText = AnimationClips[SelectedClip].Name; } ImGui.SameLine(); if (ImGui.Button("Delete Clip")) { if (SelectedClip != -1) { ImGui.OpenPopup("Are You Sure?"); EnsureClipDeletionBool = true; } } if (ImGui.BeginPopupModal("Are You Sure?", ref EnsureClipDeletionBool, ImGuiWindowFlags.AlwaysAutoResize)) { if (ImGui.Button("Yes, delete this clip")) { AnimationClips.RemoveAt(SelectedClip); ActiveFrame = 0; SelectedClip = -1; ImGui.CloseCurrentPopup(); } ImGui.SameLine(); if (ImGui.Button("No")) { ImGui.CloseCurrentPopup(); } ImGui.EndPopup(); } ImGui.SameLine(); ImGui.InputText("", ref DraggedGO, 50, ImGuiInputTextFlags.ReadOnly); if (ImGui.BeginDragDropTarget() && GameObjects_Tab.DraggedGO != null && ImGui.IsMouseReleased(ImGuiMouseButton.Left) && GameObjects_Tab.DraggedGO.GetComponent <Animator>() != null) { DraggedGO = GameObjects_Tab.DraggedGO.Name; DraggedGO_AnimClips = GameObjects_Tab.DraggedGO.GetComponent <Animator>().AnimationClips; GameObjects_Tab.DraggedGO = null; } bool AnimatorTree = ImGui.TreeNode("Animator"); if (ImGui.BeginDragDropTarget() && DraggedClip != -1 && ImGui.IsMouseReleased(ImGuiMouseButton.Left)) { bool SafeToAdd = true; foreach (Animation AI in DraggedGO_AnimClips) { if (AI.Name == AnimationClips[DraggedClip].Name) { SafeToAdd = false; break; } } if (SafeToAdd) { DraggedGO_AnimClips.Add(CopyAnimation(AnimationClips[DraggedClip])); } DraggedClip = -1; ImGui.EndDragDropTarget(); } ImGui.SameLine(); ContentWindow.HelpMarker("- To add an animation to a gameobject, \njust drag the animation player on the right \nto this drop down menu called \"Animator\". \n- To delete an existing animation from the \nanimator gameobject, just right click on an entry!"); if (AnimatorTree) { if (DraggedGO_AnimClips != null) { for (int i = 0; i < DraggedGO_AnimClips.Count; i++) { ImGui.Selectable(DraggedGO_AnimClips[i].Name); if (ImGui.IsItemClicked(ImGuiMouseButton.Right)) { DraggedGO_AnimClips.RemoveAt(i--); } if (ImGui.IsMouseDoubleClicked(ImGuiMouseButton.Left) && ImGui.IsItemHovered()) { for (int j = 0; j < AnimationClips.Count; j++) { if (AnimationClips[j].Name == DraggedGO_AnimClips[i].Name) { SelectedClip = j; AnimationClips[j].Loop = DraggedGO_AnimClips[i].Loop; AnimationClips[j].FixedTimeAmount = DraggedGO_AnimClips[i].FixedTime; AnimationClips[j].FixedTimeBewteenFrames = DraggedGO_AnimClips[i].FixedTimeBetweenFrames; AnimationClips[j].PlayReverse = DraggedGO_AnimClips[i].Reverse; AnimationClips[j].Speed = DraggedGO_AnimClips[i].Speed; ActiveFrame = 0; SearchText = DraggedGO_AnimClips[i].Name; break; } } } } } ImGui.TreePop(); } ImGui.Separator(); if (ImGui.BeginCombo("Clips", SearchText)) { for (int i = 0; i < AnimationClips.Count; i++) { if (ImGui.Selectable(AnimationClips[i].Name)) { SelectedClip = i; SearchText = AnimationClips[i].Name; ActiveFrame = 0; } } ImGui.EndCombo(); } //var CursPos = ImGui.GetCursorPos(); //ImGui.Combo("Selected Clip", ref SelectedClip, ClipsNames, AnimationClips.Count); //ImGui.SetCursorPos(CursPos); //ImGui.SetItemAllowOverlap(); //ImGui.InputText("", ref SearchText, 50); if (SelectedClip >= 0) { //Animation Player var CursPos1 = ImGui.GetCursorPos(); ImGui.SameLine(); ImGui.SetCursorPosX(ImGui.GetCursorPosX() + 90); ImGui.BeginChild("Animation Player", new Vector2(128, 128), false, ImGuiWindowFlags.NoScrollbar); if (ImGui.BeginDragDropSource()) { DraggedClip = SelectedClip; ImGui.SetDragDropPayload("Animation Clip", IntPtr.Zero, 0); ImGui.EndDragDropSource(); } if (AnimationClips[SelectedClip].Frames.Count == 0) { ImGui.Image(DragAndDropTex, new Vector2(128, 128)); } else { Frame F = AnimationClips[SelectedClip].Frames[ActiveFrame]; if (ChangeFrameTimer < (AnimationClips[SelectedClip].FixedTimeBewteenFrames ? AnimationClips[SelectedClip].FixedTimeAmount : F.Time) / AnimationClips[SelectedClip].Speed) { ChangeFrameTimer += ImGui.GetIO().DeltaTime; } else { if (AnimationClips[SelectedClip].PlayReverse) { ActiveFrame = (ActiveFrame > 0) ? ActiveFrame - 1 : AnimationClips[SelectedClip].Frames.Count - 1; } else { ActiveFrame = (ActiveFrame < AnimationClips[SelectedClip].Frames.Count - 1) ? ActiveFrame + 1 : 0; } ChangeFrameTimer = 0; } ImGui.Image(F.TexPtr, new Vector2(128, 128), new Vector2((float)F.SourceRectangle.X / F.Tex.Width, (float)F.SourceRectangle.Y / F.Tex.Height), new Vector2((float)F.SourceRectangle.Right / F.Tex.Width, (float)F.SourceRectangle.Bottom / F.Tex.Height)); } ImGui.EndChild(); ImGui.SetCursorPos(CursPos1); ImGui.InputText("Name", ref AnimationClips[SelectedClip].Name, 50); if (ImGui.IsItemDeactivatedAfterEdit()) { string[] ClipNames = new string[AnimationClips.Count]; for (int i = 0; i < AnimationClips.Count; i++) { ClipNames[i] = AnimationClips[i].Name; } AnimationClips[SelectedClip].Name = AnimationClips[SelectedClip].Name.Equals(AnimationClips[SelectedClip].Name) ? AnimationClips[SelectedClip].Name : Utility.UniqueName(AnimationClips[SelectedClip].Name, ClipNames); SearchText = AnimationClips[SelectedClip].Name; } ImGui.InputText("Tag", ref AnimationClips[SelectedClip].Tag, 50); ImGui.InputFloat("Speed", ref AnimationClips[SelectedClip].Speed); ImGui.Checkbox("Reversed", ref AnimationClips[SelectedClip].PlayReverse); ImGui.Checkbox("Loop", ref AnimationClips[SelectedClip].Loop); ImGui.Checkbox("Fixed Time Bewteen Frames", ref AnimationClips[SelectedClip].FixedTimeBewteenFrames); if (AnimationClips[SelectedClip].FixedTimeBewteenFrames) { ImGui.InputFloat("Time", ref AnimationClips[SelectedClip].FixedTimeAmount); } //Frames ImGui.Separator(); if (AnimationClips[SelectedClip].Frames.Count != 0) { ImGui.BeginChild("Frames", Vector2.Zero, false, ImGuiWindowFlags.HorizontalScrollbar); for (int i = 0; i < AnimationClips[SelectedClip].Frames.Count; i++) { Frame F = AnimationClips[SelectedClip].Frames[i]; if (F.TexPtr == default(IntPtr)) { F.TexPtr = Scene.GuiRenderer.BindTexture(F.Tex); } ImGui.BeginGroup(); ImGui.ImageButton(F.TexPtr, new Vector2(64, 64), new Vector2((float)F.SourceRectangle.X / F.Tex.Width, (float)F.SourceRectangle.Y / F.Tex.Height), new Vector2((float)F.SourceRectangle.Right / F.Tex.Width, (float)F.SourceRectangle.Bottom / F.Tex.Height)); if (ImGui.IsItemClicked(ImGuiMouseButton.Right)) { AnimationClips[SelectedClip].Frames.RemoveAt(i--); ActiveFrame = 0; } if (ImGui.BeginDragDropSource()) { DraggedFrame = i; ImGui.SetDragDropPayload("Dragged Frame", IntPtr.Zero, 0); ImGui.EndDragDropSource(); } if (ImGui.BeginDragDropTarget() && DraggedFrame != -1 && ImGui.IsMouseReleased(ImGuiMouseButton.Left)) { Frame Source = AnimationClips[SelectedClip].Frames[DraggedFrame]; Frame Target = AnimationClips[SelectedClip].Frames[i]; AnimationClips[SelectedClip].Frames.RemoveAt(DraggedFrame); AnimationClips[SelectedClip].Frames.Insert(DraggedFrame, Target); AnimationClips[SelectedClip].Frames.RemoveAt(i); AnimationClips[SelectedClip].Frames.Insert(i, Source); DraggedFrame = -1; ImGui.EndDragDropTarget(); } if (!AnimationClips[SelectedClip].FixedTimeBewteenFrames) { ImGui.PushItemWidth(64); ImGui.PushID(i); ImGui.SliderFloat("", ref F.Time, 0, 10); ImGui.PopID(); ImGui.PopItemWidth(); } ImGui.EndGroup(); ImGui.SameLine(); } ImGui.EndChild(); ImGui.SameLine(); } ImGui.ImageButton(DragAndDropTex, new Vector2(64, 64)); //Drag and Drop if (ImGui.BeginDragDropTarget() && ImGui.IsMouseReleased(ImGuiMouseButton.Left)) { if (ContentWindow.DraggedAsset != null) { if (ContentWindow.DraggedAsset is string) //Whole texture { Frame NewFrame = new Frame(); bool Safe = true; try { NewFrame.Tex = Setup.Content.Load <Texture2D>((string)ContentWindow.DraggedAsset); } catch (Exception E) { Safe = false; Utility.Log(E.Message); } if (Safe) { NewFrame.SourceRectangle = NewFrame.Tex.Bounds; NewFrame.Time = 0.25f; NewFrame.TexPtr = Scene.GuiRenderer.BindTexture(NewFrame.Tex); AnimationClips[SelectedClip].Frames.Add(NewFrame); ActiveFrame = 0; } } else if (ContentWindow.DraggedAsset is KeyValuePair <string, Vector4> ) //Sliced Texture { Frame NewFrame = new Frame(); bool Safe = true; try { NewFrame.Tex = Setup.Content.Load <Texture2D>(((KeyValuePair <string, Vector4>)ContentWindow.DraggedAsset).Key); } catch (Exception E) { Safe = false; Utility.Log(E.Message); } if (Safe) { Vector4 SrcRect = ((KeyValuePair <string, Vector4>)ContentWindow.DraggedAsset).Value; NewFrame.SourceRectangle = new Microsoft.Xna.Framework.Rectangle((int)Math.Round(SrcRect.X * (NewFrame.Tex.Width / 10000.0f)), (int)Math.Round(SrcRect.Y * (NewFrame.Tex.Height / 10000.0f)), (int)Math.Round(SrcRect.Z * (NewFrame.Tex.Width / 10000.0f)), (int)Math.Round(SrcRect.W * (NewFrame.Tex.Height / 10000.0f))); NewFrame.Time = 0.25f; NewFrame.TexPtr = Scene.GuiRenderer.BindTexture(NewFrame.Tex); AnimationClips[SelectedClip].Frames.Add(NewFrame); ActiveFrame = 0; } } ContentWindow.DraggedAsset = null; } else if (slicedTexs.Key != null) { bool Safe = true; Texture2D T2D = null; try { T2D = Setup.Content.Load <Texture2D>(slicedTexs.Key); } catch (Exception E) { Safe = false; Utility.Log(E.Message); } if (Safe) { foreach (Microsoft.Xna.Framework.Rectangle Rect in slicedTexs.Value) { Frame NewFrame = new Frame(); NewFrame.Tex = T2D; Vector4 SrcRect = new Vector4(Rect.X, Rect.Y, Rect.Width, Rect.Height); NewFrame.SourceRectangle = new Microsoft.Xna.Framework.Rectangle((int)Math.Round(SrcRect.X * (NewFrame.Tex.Width / 10000.0f)), (int)Math.Round(SrcRect.Y * (NewFrame.Tex.Height / 10000.0f)), (int)Math.Round(SrcRect.Z * (NewFrame.Tex.Width / 10000.0f)), (int)Math.Round(SrcRect.W * (NewFrame.Tex.Height / 10000.0f))); NewFrame.Time = 0.25f; NewFrame.TexPtr = Scene.GuiRenderer.BindTexture(NewFrame.Tex); AnimationClips[SelectedClip].Frames.Add(NewFrame); } ActiveFrame = 0; } slicedTexs = new KeyValuePair <string, List <Microsoft.Xna.Framework.Rectangle> >(null, null); } ImGui.EndDragDropTarget(); } } ImGui.End(); ImGui.PopStyleColor(); ImGui.PopStyleVar(); } }
private static unsafe void SubmitEntitiesWindow(EntityAdmin admin, Dictionary <Entity, List <int> > entityToComponentGroups) { ImGui.Begin("Entities and Components"); bool createEntity = SubmitAddComponent("Create Entity", out Type componentType); Entity entityToDestroy = SelectedEntityComponent as Entity; bool disabled = entityToDestroy == null; if (disabled) { Util.ImGuiUtil.BeginDisable(); } if (ImGui.Button("Destroy Entity") && !disabled) { admin.DestroyEntity(entityToDestroy); } if (disabled) { Util.ImGuiUtil.EndDisable(); } ImGui.Separator(); ImGui.BeginChild("scrolling", Vector2.Zero, false, ImGuiWindowFlags.HorizontalScrollbar); var entities = EntityAdminUtil.GetEntities(admin); foreach (var entity in entities) { var components = entity.Components; ImGuiTreeNodeFlags nodeFlags = ImGuiTreeNodeFlags.OpenOnArrow | ImGuiTreeNodeFlags.OpenOnDoubleClick | ImGuiTreeNodeFlags.SpanAvailWidth; // OpenOnDoubleClick doesn't seem to work. Not sure why. if (entity.Components.Count == 0) { nodeFlags |= ImGuiTreeNodeFlags.Leaf; } if (entity == SelectedEntityComponent) { nodeFlags |= ImGuiTreeNodeFlags.Selected; if (scrollEntitiesView) { ImGui.SetScrollHereY(); } } if (entity.HasComponent <DontDestroyOnClear>(true)) { ImGui.PushFont(ImGuiController.BoldFont); } if (!entity.IsActive) { ImGui.PushStyleColor(ImGuiCol.Text, new Vector4(0.5f, 0.5f, 0.5f, 1f)); } bool errorInEntity = false; for (int i = 0; i < components.Count; i++) { if (!RequiresSystem.HasECSSystemForType(components[i].GetType(), HostHelper.GameSystems, out _)) { errorInEntity = true; } if (components[i] == SelectedEntityComponent) { ImGui.SetNextItemOpen(true); } } string componentGroupsText = string.Empty; if (entityToComponentGroups.ContainsKey(entity)) { foreach (int groupNum in entityToComponentGroups[entity]) { componentGroupsText = $"({groupNum}){componentGroupsText}"; } if (entityToComponentGroups[entity].Count() > 1) { errorInEntity = true; } } if (errorInEntity) { ImGui.PushStyleColor(ImGuiCol.Text, new Vector4(1f, 0f, 0f, 1f)); } string entityTransformText = !entity.HasComponent <Transform>(true) ? "~ " : ""; string entityLabelText = $"{componentGroupsText}{entityTransformText}{entity.Name}"; bool expanded = ImGui.TreeNodeEx(entity.Guid.ToString(), nodeFlags, entityLabelText); if (errorInEntity) { ImGui.PopStyleColor(); } if (!entity.IsActive) { ImGui.PopStyleColor(); } if (entity.HasComponent <DontDestroyOnClear>(true)) { ImGui.PopFont(); } if (ImGui.IsItemClicked()) { SelectedEntityComponent = entity; scrollSceneGraphView = true; } if (ImGui.BeginDragDropSource()) { ImGui.SetDragDropPayload(PAYLOAD_STRING, IntPtr.Zero, 0); // Payload is needed to trigger BeginDragDropTarget() draggedObject = entity; ImGui.Text(entity.Name); ImGui.EndDragDropSource(); } if (expanded) { for (int i = 0; i < components.Count; i++) { Component component = components[i]; nodeFlags = ImGuiTreeNodeFlags.Leaf | ImGuiTreeNodeFlags.SpanAvailWidth | ImGuiTreeNodeFlags.NoTreePushOnOpen; // This last one means that you can't do aImGui.TreePop(); or things will be messed up. if (component == SelectedEntityComponent) { nodeFlags |= ImGuiTreeNodeFlags.Selected; if (scrollEntitiesView) { ImGui.SetScrollHereY(); } } if (!component.IsActive) { ImGui.PushStyleColor(ImGuiCol.Text, new Vector4(0.5f, 0.5f, 0.5f, 1f)); } bool hasRequiredSystems = RequiresSystem.HasECSSystemForType(component.GetType(), HostHelper.GameSystems, out _); if (!hasRequiredSystems) { ImGui.PushStyleColor(ImGuiCol.Text, new Vector4(1f, 0f, 0f, 1f)); } ImGui.TreeNodeEx(component.Guid.ToString(), nodeFlags, component.Name); if (!hasRequiredSystems) { ImGui.PopStyleColor(); } if (!component.IsActive) { ImGui.PopStyleColor(); } if (ImGui.IsItemClicked()) { SelectedEntityComponent = component; scrollSceneGraphView = true; } if (ImGui.BeginDragDropSource()) { ImGui.SetDragDropPayload(PAYLOAD_STRING, IntPtr.Zero, 0); // Payload is needed to trigger BeginDragDropTarget() draggedObject = component; ImGui.Text(component.Name); ImGui.EndDragDropSource(); } } ImGui.TreePop(); } } scrollEntitiesView = false; if (createEntity) { var entity = admin.CreateEntity($"{componentType.Name}'s Entity"); SelectedEntityComponent = admin.AddComponent(entity, componentType); scrollEntitiesView = true; // For some reason this doesn't work half the time -_- Not sure why... } ImGui.End(); }
public static bool BeginDragDropSource() { return(ImGui.BeginDragDropSource()); }