Merge branch 'davevanegdom-Double-Click-Scene-Node-Actions'
This commit is contained in:
@@ -105,6 +105,33 @@ namespace FlaxEditor.Modules
|
||||
Editor.Windows.ContentWin.NewItem(proxy, actor, contentItem => OnPrefabCreated(contentItem, actor, prefabWindow), actor.Name, rename);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens a prefab editor window.
|
||||
/// </summary>
|
||||
public void OpenPrefab(ActorNode actorNode)
|
||||
{
|
||||
if (actorNode != null)
|
||||
OpenPrefab(actorNode.Actor.PrefabID);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens a prefab editor window.
|
||||
/// </summary>
|
||||
public void OpenPrefab(Guid prefabID = default)
|
||||
{
|
||||
if (prefabID == Guid.Empty)
|
||||
{
|
||||
var selection = Editor.SceneEditing.Selection.Where(x => x is ActorNode actorNode && actorNode.HasPrefabLink).ToList().BuildNodesParents();
|
||||
if (selection.Count == 0 || !((ActorNode)selection[0]).Actor.HasPrefabLink)
|
||||
return;
|
||||
prefabID = ((ActorNode)selection[0]).Actor.PrefabID;
|
||||
}
|
||||
|
||||
var item = Editor.ContentDatabase.Find(prefabID);
|
||||
if (item != null)
|
||||
Editor.ContentEditing.Open(item);
|
||||
}
|
||||
|
||||
private void OnPrefabCreated(ContentItem contentItem, Actor actor, Windows.Assets.PrefabWindow prefabWindow)
|
||||
{
|
||||
if (contentItem is PrefabItem prefabItem)
|
||||
|
||||
@@ -8,6 +8,7 @@ using FlaxEditor.CustomEditors;
|
||||
using FlaxEditor.CustomEditors.Elements;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
using static FlaxEditor.Viewport.EditorViewport;
|
||||
|
||||
namespace FlaxEditor.Options
|
||||
{
|
||||
@@ -18,7 +19,7 @@ namespace FlaxEditor.Options
|
||||
[HideInEditor]
|
||||
[TypeConverter(typeof(InputBindingConverter))]
|
||||
[CustomEditor(typeof(InputBindingEditor))]
|
||||
public struct InputBinding
|
||||
public struct InputBinding : IEquatable<InputBinding>
|
||||
{
|
||||
/// <summary>
|
||||
/// The key to bind.
|
||||
@@ -251,6 +252,40 @@ namespace FlaxEditor.Options
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Equals(InputBinding other)
|
||||
{
|
||||
return Key == other.Key && Modifier1 == other.Modifier1 && Modifier2 == other.Modifier2;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return obj is InputBinding other && Equals(other);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return HashCode.Combine((int)Key, (int)Modifier1, (int)Modifier2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two values.
|
||||
/// </summary>
|
||||
public static bool operator ==(InputBinding left, InputBinding right)
|
||||
{
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two values.
|
||||
/// </summary>
|
||||
public static bool operator !=(InputBinding left, InputBinding right)
|
||||
{
|
||||
return !left.Equals(right);
|
||||
}
|
||||
}
|
||||
|
||||
class InputBindingConverter : TypeConverter
|
||||
@@ -522,5 +557,27 @@ namespace FlaxEditor.Options
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes a specific binding.
|
||||
/// </summary>
|
||||
/// <param name="editor">The editor instance.</param>
|
||||
/// <param name="binding">The binding to execute.</param>
|
||||
/// <returns>True if event has been handled, otherwise false.</returns>
|
||||
public bool Invoke(Editor editor, InputBinding binding)
|
||||
{
|
||||
if (binding == new InputBinding())
|
||||
return false;
|
||||
var options = editor.Options.Options.Input;
|
||||
for (int i = 0; i < Bindings.Count; i++)
|
||||
{
|
||||
if (Bindings[i].Binder(options) == binding)
|
||||
{
|
||||
Bindings[i].Callback();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,32 @@ using FlaxEngine;
|
||||
|
||||
namespace FlaxEditor.Options
|
||||
{
|
||||
/// <summary>
|
||||
/// Action to perform when a Scene Node receive a double mouse left click.
|
||||
/// </summary>
|
||||
public enum SceneNodeDoubleClick
|
||||
{
|
||||
/// <summary>
|
||||
/// Toggles expand/state of the node.
|
||||
/// </summary>
|
||||
Expand,
|
||||
|
||||
/// <summary>
|
||||
/// Rename the node.
|
||||
/// </summary>
|
||||
RenameActor,
|
||||
|
||||
/// <summary>
|
||||
/// Focus the object in the viewport.
|
||||
/// </summary>
|
||||
FocusActor,
|
||||
|
||||
/// <summary>
|
||||
/// If possible, open the scene node in an associated Editor (eg. Prefab Editor).
|
||||
/// </summary>
|
||||
OpenPrefab,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Input editor options data container.
|
||||
/// </summary>
|
||||
@@ -344,6 +370,10 @@ namespace FlaxEditor.Options
|
||||
[EditorDisplay("Interface"), EditorOrder(2020)]
|
||||
public InputBinding PreviousTab = new InputBinding(KeyboardKeys.Tab, KeyboardKeys.Control, KeyboardKeys.Shift);
|
||||
|
||||
[DefaultValue(SceneNodeDoubleClick.None)]
|
||||
[EditorDisplay("Interface"), EditorOrder(2030)]
|
||||
public SceneNodeDoubleClick DoubleClickSceneNode = SceneNodeDoubleClick.None;
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ using FlaxEditor.Content;
|
||||
using FlaxEditor.GUI;
|
||||
using FlaxEditor.GUI.Drag;
|
||||
using FlaxEditor.GUI.Tree;
|
||||
using FlaxEditor.Options;
|
||||
using FlaxEditor.Scripting;
|
||||
using FlaxEditor.Utilities;
|
||||
using FlaxEditor.Windows;
|
||||
@@ -15,7 +16,6 @@ using FlaxEditor.Windows.Assets;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
using FlaxEngine.Utilities;
|
||||
using Object = FlaxEngine.Object;
|
||||
|
||||
namespace FlaxEditor.SceneGraph.GUI
|
||||
{
|
||||
@@ -393,7 +393,7 @@ namespace FlaxEditor.SceneGraph.GUI
|
||||
/// <summary>
|
||||
/// Starts the actor renaming action.
|
||||
/// </summary>
|
||||
public void StartRenaming(EditorWindow window, Panel treePanel = null)
|
||||
public void StartRenaming(EditorWindow window = null, Panel treePanel = null)
|
||||
{
|
||||
// Block renaming during scripts reload
|
||||
if (Editor.Instance.ProgressReporting.CompileScripts.IsActive)
|
||||
@@ -461,6 +461,30 @@ namespace FlaxEditor.SceneGraph.GUI
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override bool OnMouseDoubleClickHeader(ref Float2 location, MouseButton button)
|
||||
{
|
||||
if (button == MouseButton.Left)
|
||||
{
|
||||
var sceneContext = this.GetSceneContext();
|
||||
switch (Editor.Instance.Options.Options.Input.DoubleClickSceneNode)
|
||||
{
|
||||
case SceneNodeDoubleClick.RenameActor:
|
||||
sceneContext.RenameSelection();
|
||||
return true;
|
||||
case SceneNodeDoubleClick.FocusActor:
|
||||
sceneContext.FocusSelection();
|
||||
return true;
|
||||
case SceneNodeDoubleClick.OpenPrefab:
|
||||
Editor.Instance.Prefabs.OpenPrefab(ActorNode);
|
||||
return true;
|
||||
case SceneNodeDoubleClick.Expand:
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
return base.OnMouseDoubleClickHeader(ref location, button);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override DragDropEffect OnDragEnterHeader(DragData data)
|
||||
{
|
||||
|
||||
@@ -1544,5 +1544,12 @@ namespace FlaxEditor.Utilities
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
internal static ISceneContextWindow GetSceneContext(this Control c)
|
||||
{
|
||||
while (c != null && !(c is ISceneContextWindow))
|
||||
c = c.Parent;
|
||||
return c as ISceneContextWindow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FlaxEditor.Content;
|
||||
using FlaxEditor.GUI.ContextMenu;
|
||||
using FlaxEditor.GUI.Drag;
|
||||
@@ -86,7 +85,7 @@ namespace FlaxEditor.Windows.Assets
|
||||
{
|
||||
return Editor.Instance.CodeEditing.Actors.Get().Contains(actorType);
|
||||
}
|
||||
|
||||
|
||||
private static bool ValidateDragControlType(ScriptType controlType)
|
||||
{
|
||||
return Editor.Instance.CodeEditing.Controls.Get().Contains(controlType);
|
||||
@@ -171,7 +170,8 @@ namespace FlaxEditor.Windows.Assets
|
||||
var actor = item.OnEditorDrop(this);
|
||||
actor.Name = item.ShortName;
|
||||
_window.Spawn(actor);
|
||||
var graphNode = _window.Graph.Root.Find(actor);;
|
||||
var graphNode = _window.Graph.Root.Find(actor);
|
||||
;
|
||||
if (graphNode != null)
|
||||
graphNodes.Add(graphNode);
|
||||
}
|
||||
@@ -235,7 +235,8 @@ namespace FlaxEditor.Windows.Assets
|
||||
}
|
||||
actor.Name = actorType.Name;
|
||||
_window.Spawn(actor);
|
||||
var graphNode = _window.Graph.Root.Find(actor);;
|
||||
var graphNode = _window.Graph.Root.Find(actor);
|
||||
;
|
||||
if (graphNode != null)
|
||||
graphNodes.Add(graphNode);
|
||||
}
|
||||
@@ -290,7 +291,7 @@ namespace FlaxEditor.Windows.Assets
|
||||
|
||||
// Basic editing options
|
||||
|
||||
var b = contextMenu.AddButton("Rename", Rename);
|
||||
var b = contextMenu.AddButton("Rename", RenameSelection);
|
||||
b.Enabled = isSingleActorSelected;
|
||||
|
||||
b = contextMenu.AddButton("Duplicate", Duplicate);
|
||||
@@ -414,7 +415,8 @@ namespace FlaxEditor.Windows.Assets
|
||||
contextMenu.Show(parent, location);
|
||||
}
|
||||
|
||||
private void Rename()
|
||||
/// <inheritdoc />
|
||||
public void RenameSelection()
|
||||
{
|
||||
var selection = Selection;
|
||||
if (selection.Count != 0 && selection[0] is ActorNode actor)
|
||||
@@ -425,6 +427,12 @@ namespace FlaxEditor.Windows.Assets
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void FocusSelection()
|
||||
{
|
||||
_viewport.FocusSelection();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Spawns the specified actor to the prefab (adds actor to root).
|
||||
/// </summary>
|
||||
@@ -468,7 +476,7 @@ namespace FlaxEditor.Windows.Assets
|
||||
|
||||
// Spawn it
|
||||
Spawn(actor);
|
||||
Rename();
|
||||
RenameSelection();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace FlaxEditor.Windows.Assets
|
||||
/// </summary>
|
||||
/// <seealso cref="Prefab" />
|
||||
/// <seealso cref="FlaxEditor.Windows.Assets.AssetEditorWindow" />
|
||||
public sealed partial class PrefabWindow : AssetEditorWindowBase<Prefab>, IPresenterOwner
|
||||
public sealed partial class PrefabWindow : AssetEditorWindowBase<Prefab>, IPresenterOwner, ISceneContextWindow
|
||||
{
|
||||
private readonly SplitPanel _split1;
|
||||
private readonly SplitPanel _split2;
|
||||
@@ -212,8 +212,8 @@ namespace FlaxEditor.Windows.Assets
|
||||
InputActions.Add(options => options.Paste, Paste);
|
||||
InputActions.Add(options => options.Duplicate, Duplicate);
|
||||
InputActions.Add(options => options.Delete, Delete);
|
||||
InputActions.Add(options => options.Rename, Rename);
|
||||
InputActions.Add(options => options.FocusSelection, _viewport.FocusSelection);
|
||||
InputActions.Add(options => options.Rename, RenameSelection);
|
||||
InputActions.Add(options => options.FocusSelection, FocusSelection);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,14 +1,32 @@
|
||||
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
||||
|
||||
using FlaxEditor.SceneGraph;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
|
||||
namespace FlaxEditor.Windows
|
||||
{
|
||||
/// <summary>
|
||||
/// Shared interface for scene editing utilities.
|
||||
/// </summary>
|
||||
public interface ISceneContextWindow
|
||||
{
|
||||
/// <summary>
|
||||
/// Opends popup for renaming selected objects.
|
||||
/// </summary>
|
||||
void RenameSelection();
|
||||
|
||||
/// <summary>
|
||||
/// Focuses selected objects.
|
||||
/// </summary>
|
||||
void FocusSelection();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Base class for editor windows dedicated to scene editing.
|
||||
/// </summary>
|
||||
/// <seealso cref="FlaxEditor.Windows.EditorWindow" />
|
||||
public abstract class SceneEditorWindow : EditorWindow
|
||||
public abstract class SceneEditorWindow : EditorWindow, ISceneContextWindow
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SceneEditorWindow"/> class.
|
||||
@@ -21,5 +39,38 @@ namespace FlaxEditor.Windows
|
||||
{
|
||||
FlaxEditor.Utilities.Utils.SetupCommonInputActions(this);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void FocusSelection()
|
||||
{
|
||||
Editor.Windows.EditWin.Viewport.FocusSelection();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void RenameSelection()
|
||||
{
|
||||
var selection = Editor.SceneEditing.Selection;
|
||||
var selectionCount = selection.Count;
|
||||
|
||||
// Show a window with options to rename multiple actors.
|
||||
if (selectionCount > 1)
|
||||
{
|
||||
var selectedActors = new Actor[selectionCount];
|
||||
|
||||
for (int i = 0; i < selectionCount; i++)
|
||||
if (selection[i] is ActorNode actorNode)
|
||||
selectedActors[i] = actorNode.Actor;
|
||||
|
||||
RenameWindow.Show(selectedActors, Editor);
|
||||
return;
|
||||
}
|
||||
|
||||
if (selectionCount != 0 && selection[0] is ActorNode actor)
|
||||
{
|
||||
Editor.SceneEditing.Select(actor);
|
||||
var sceneWindow = Editor.Windows.SceneWin;
|
||||
actor.TreeNode.StartRenaming(sceneWindow, sceneWindow.SceneTreePanel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace FlaxEditor.Windows
|
||||
|
||||
// Basic editing options
|
||||
var firstSelection = hasSthSelected ? Editor.SceneEditing.Selection[0] as ActorNode : null;
|
||||
b = contextMenu.AddButton("Rename", inputOptions.Rename, Rename);
|
||||
b = contextMenu.AddButton("Rename", inputOptions.Rename, RenameSelection);
|
||||
b.Enabled = hasSthSelected;
|
||||
b = contextMenu.AddButton("Duplicate", inputOptions.Duplicate, Editor.SceneEditing.Duplicate);
|
||||
b.Enabled = hasSthSelected && (firstSelection != null ? firstSelection.CanDuplicate : true);
|
||||
@@ -145,6 +145,7 @@ namespace FlaxEditor.Windows
|
||||
bool hasPrefabLink = canEditScene && isSingleActorSelected && (firstSelection != null ? firstSelection.HasPrefabLink : false);
|
||||
if (hasPrefabLink)
|
||||
{
|
||||
contextMenu.AddButton("Open Prefab", () => Editor.Prefabs.OpenPrefab(firstSelection));
|
||||
contextMenu.AddButton("Select Prefab", Editor.Prefabs.SelectPrefab);
|
||||
contextMenu.AddButton("Break Prefab Link", Editor.Prefabs.BreakLinks);
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ namespace FlaxEditor.Windows
|
||||
InputActions.Add(options => options.ScaleMode, () => Editor.MainTransformGizmo.ActiveMode = TransformGizmoBase.Mode.Scale);
|
||||
InputActions.Add(options => options.FocusSelection, () => Editor.Windows.EditWin.Viewport.FocusSelection());
|
||||
InputActions.Add(options => options.LockFocusSelection, () => Editor.Windows.EditWin.Viewport.LockFocusSelection());
|
||||
InputActions.Add(options => options.Rename, Rename);
|
||||
InputActions.Add(options => options.Rename, RenameSelection);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -143,31 +143,6 @@ namespace FlaxEditor.Windows
|
||||
PerformLayout();
|
||||
}
|
||||
|
||||
private void Rename()
|
||||
{
|
||||
var selection = Editor.SceneEditing.Selection;
|
||||
var selectionCount = selection.Count;
|
||||
|
||||
// Show a window with options to rename multiple actors.
|
||||
if (selectionCount > 1)
|
||||
{
|
||||
var selectedActors = new Actor[selectionCount];
|
||||
|
||||
for (int i = 0; i < selectionCount; i++)
|
||||
if (selection[i] is ActorNode actorNode)
|
||||
selectedActors[i] = actorNode.Actor;
|
||||
|
||||
RenameWindow.Show(selectedActors, Editor);
|
||||
return;
|
||||
}
|
||||
|
||||
if (selectionCount != 0 && selection[0] is ActorNode actor)
|
||||
{
|
||||
Editor.SceneEditing.Select(actor);
|
||||
actor.TreeNode.StartRenaming(this, _sceneTreePanel);
|
||||
}
|
||||
}
|
||||
|
||||
private void Spawn(Type type)
|
||||
{
|
||||
// Create actor
|
||||
@@ -197,7 +172,7 @@ namespace FlaxEditor.Windows
|
||||
Editor.SceneEditing.Spawn(actor, parentActor);
|
||||
|
||||
Editor.SceneEditing.Select(actor);
|
||||
Rename();
|
||||
RenameSelection();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -293,7 +268,7 @@ namespace FlaxEditor.Windows
|
||||
{
|
||||
return Editor.Instance.CodeEditing.Actors.Get().Contains(actorType);
|
||||
}
|
||||
|
||||
|
||||
private static bool ValidateDragControlType(ScriptType controlType)
|
||||
{
|
||||
return Editor.Instance.CodeEditing.Controls.Get().Contains(controlType);
|
||||
|
||||
Reference in New Issue
Block a user