Merge remote-tracking branch 'origin/master' into sdl_platform

This commit is contained in:
2025-06-02 18:15:16 +03:00
124 changed files with 1244 additions and 436 deletions

View File

@@ -13,6 +13,11 @@ namespace FlaxEditor.Content.Create
/// <inheritdoc />
public string ResultUrl { get; }
/// <summary>
/// Gets a value indicating wether a file can be created based on the current settings.
/// </summary>
public abstract bool CanBeCreated { get; }
/// <summary>
/// Gets a value indicating whether this entry has settings to modify.
/// </summary>

View File

@@ -60,7 +60,8 @@ namespace FlaxEditor.Content.Create
Text = "Create",
AnchorPreset = AnchorPresets.BottomRight,
Offsets = new Margin(-ButtonsWidth - ButtonsMargin, ButtonsWidth, -ButtonsHeight - ButtonsMargin, ButtonsHeight),
Parent = this
Parent = this,
Enabled = entry.CanBeCreated,
};
createButton.Clicked += OnSubmit;
var cancelButton = new Button
@@ -68,7 +69,7 @@ namespace FlaxEditor.Content.Create
Text = "Cancel",
AnchorPreset = AnchorPresets.BottomRight,
Offsets = new Margin(-ButtonsWidth - ButtonsMargin - ButtonsWidth - ButtonsMargin, ButtonsWidth, -ButtonsHeight - ButtonsMargin, ButtonsHeight),
Parent = this
Parent = this,
};
cancelButton.Clicked += OnCancel;
@@ -77,7 +78,7 @@ namespace FlaxEditor.Content.Create
{
AnchorPreset = AnchorPresets.HorizontalStretchTop,
Offsets = new Margin(2, 2, infoLabel.Bottom + 2, EditorHeight),
Parent = this
Parent = this,
};
// Settings editor
@@ -87,6 +88,7 @@ namespace FlaxEditor.Content.Create
_dialogSize = new Float2(TotalWidth, panel.Bottom);
_settingsEditor.Select(_entry.Settings);
_settingsEditor.Modified += () => createButton.Enabled = _entry.CanBeCreated;
}
/// <inheritdoc />

View File

@@ -12,6 +12,9 @@ namespace FlaxEditor.Content.Create
/// <seealso cref="FlaxEditor.Content.Create.CreateFileEntry" />
public class ParticleEmitterCreateEntry : CreateFileEntry
{
/// <inheritdoc/>
public override bool CanBeCreated => true;
/// <summary>
/// Types of the emitter templates that can be created.
/// </summary>

View File

@@ -14,6 +14,9 @@ namespace FlaxEditor.Content.Create
/// <seealso cref="FlaxEditor.Content.Create.CreateFileEntry" />
public class PrefabCreateEntry : CreateFileEntry
{
/// <inheritdoc />
public override bool CanBeCreated => _options.RootActorType != null;
/// <summary>
/// The create options.
/// </summary>
@@ -73,6 +76,9 @@ namespace FlaxEditor.Content.Create
/// <seealso cref="FlaxEditor.Content.Create.CreateFileEntry" />
public class WidgetCreateEntry : CreateFileEntry
{
/// <inheritdoc/>
public override bool CanBeCreated => _options.RootControlType != null;
/// <summary>
/// The create options.
/// </summary>

View File

@@ -17,6 +17,8 @@ namespace FlaxEditor.Content.Create
/// <seealso cref="FlaxEditor.Content.Create.CreateFileEntry" />
internal class SettingsCreateEntry : CreateFileEntry
{
public override bool CanBeCreated => _options.Type != null;
internal class Options
{
[Tooltip("The settings type.")]

View File

@@ -11,6 +11,9 @@ namespace FlaxEditor.Content.Create
/// <seealso cref="FlaxEditor.Content.Create.CreateFileEntry" />
public class VisualScriptCreateEntry : CreateFileEntry
{
/// <inheritdoc/>
public override bool CanBeCreated => _options.BaseClass != null;
/// <summary>
/// The create options.
/// </summary>

View File

@@ -65,6 +65,9 @@ namespace FlaxEditor.Content
/// <seealso cref="FlaxEditor.Content.Create.CreateFileEntry" />
public class GenericJsonCreateEntry : CreateFileEntry
{
/// <inheritdoc/>
public override bool CanBeCreated => _options.Type != null;
/// <summary>
/// The create options.
/// </summary>

View File

@@ -33,8 +33,8 @@ namespace FlaxEditor
private void Set(CustomEditorWindow value)
{
_customEditor = value;
_presenter.Select(value);
_presenter.OverrideEditor = value;
_presenter.Select(value);
}
/// <inheritdoc />

View File

@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using FlaxEditor.SceneGraph;
using FlaxEditor.Scripting;
using FlaxEngine;
using FlaxEngine.GUI;
@@ -52,6 +53,16 @@ namespace FlaxEditor.CustomEditors
/// </summary>
/// <param name="nodes">The nodes to select</param>
public void Select(List<SceneGraph.SceneGraphNode> nodes);
/// <summary>
/// Gets the current selection.
/// </summary>
public List<SceneGraphNode> Selection { get; }
/// <summary>
/// Indication of if the properties window is locked on specific objects.
/// </summary>
public bool LockSelection { get; set; }
}
/// <summary>
@@ -81,6 +92,8 @@ namespace FlaxEditor.CustomEditors
Offsets = Margin.Zero;
Pivot = Float2.Zero;
IsScrollable = true;
Spacing = Utilities.Constants.UIMargin;
Margin = new Margin(Utilities.Constants.UIMargin);
}
/// <inheritdoc />
@@ -95,7 +108,7 @@ namespace FlaxEditor.CustomEditors
{
FlaxEditor.Editor.LogWarning(ex);
// Refresh layout on errors to reduce lgo spam
// Refresh layout on errors to reduce log spam
_presenter.BuildLayout();
}
@@ -132,6 +145,8 @@ namespace FlaxEditor.CustomEditors
get => _overrideEditor;
set
{
if (_overrideEditor == value)
return;
_overrideEditor = value;
RebuildLayout();
}
@@ -200,7 +215,6 @@ namespace FlaxEditor.CustomEditors
protected override void Deinitialize()
{
Editor = null;
_overrideEditor = null;
base.Deinitialize();
}

View File

@@ -9,7 +9,6 @@ using FlaxEditor.CustomEditors.Elements;
using FlaxEditor.GUI;
using FlaxEditor.GUI.ContextMenu;
using FlaxEditor.GUI.Tree;
using FlaxEditor.Modules;
using FlaxEditor.Scripting;
using FlaxEditor.Windows;
using FlaxEditor.Windows.Assets;
@@ -71,14 +70,14 @@ namespace FlaxEditor.CustomEditors.Dedicated
// Display prefab UI (when displaying object inside Prefab Window then display only nested prefabs)
prefab.GetNestedObject(ref prefabObjectId, out var nestedPrefabId, out var nestedPrefabObjectId);
var nestedPrefab = FlaxEngine.Content.Load<Prefab>(nestedPrefabId);
var panel = layout.CustomContainer<UniformGridPanel>();
var panel = layout.UniformGrid();
panel.CustomControl.Height = 20.0f;
panel.CustomControl.SlotsVertically = 1;
if (Presenter == Editor.Instance.Windows.PropertiesWin.Presenter || nestedPrefab)
{
var targetPrefab = nestedPrefab ?? prefab;
panel.CustomControl.SlotsHorizontally = 3;
// Selecting actor prefab asset
var selectPrefab = panel.Button("Select Prefab");
selectPrefab.Button.Clicked += () =>
@@ -133,35 +132,22 @@ namespace FlaxEditor.CustomEditors.Dedicated
var actor = (Actor)Values[0];
var scriptType = TypeUtils.GetType(actor.TypeName);
var item = scriptType.ContentItem;
if (Presenter.Owner is PropertiesWindow propertiesWindow)
if (Presenter.Owner != null)
{
var lockButton = cm.AddButton(propertiesWindow.LockObjects ? "Unlock" : "Lock");
var lockButton = cm.AddButton(Presenter.Owner.LockSelection ? "Unlock" : "Lock");
lockButton.ButtonClicked += button =>
{
propertiesWindow.LockObjects = !propertiesWindow.LockObjects;
var owner = Presenter?.Owner;
if (owner == null)
return;
owner.LockSelection = !owner.LockSelection;
// Reselect current selection
if (!propertiesWindow.LockObjects && Editor.Instance.SceneEditing.SelectionCount > 0)
if (!owner.LockSelection && owner.Selection.Count > 0)
{
var cachedSelection = Editor.Instance.SceneEditing.Selection.ToArray();
Editor.Instance.SceneEditing.Select(null);
Editor.Instance.SceneEditing.Select(cachedSelection);
}
};
}
else if (Presenter.Owner is PrefabWindow prefabWindow)
{
var lockButton = cm.AddButton(prefabWindow.LockSelectedObjects ? "Unlock" : "Lock");
lockButton.ButtonClicked += button =>
{
prefabWindow.LockSelectedObjects = !prefabWindow.LockSelectedObjects;
// Reselect current selection
if (!prefabWindow.LockSelectedObjects && prefabWindow.Selection.Count > 0)
{
var cachedSelection = prefabWindow.Selection.ToList();
prefabWindow.Select(null);
prefabWindow.Select(cachedSelection);
var cachedSelection = owner.Selection.ToList();
owner.Select(null);
owner.Select(cachedSelection);
}
};
}
@@ -258,7 +244,17 @@ namespace FlaxEditor.CustomEditors.Dedicated
else if (editor.Values[0] is SceneObject sceneObject)
{
node.TextColor = sceneObject.HasPrefabLink ? FlaxEngine.GUI.Style.Current.ProgressNormal : FlaxEngine.GUI.Style.Current.BackgroundSelected;
node.Text = Utilities.Utils.GetPropertyNameUI(sceneObject.GetType().Name);
if (editor.Values.Info != ScriptMemberInfo.Null)
{
if (editor.Values.GetAttributes().FirstOrDefault(x => x is EditorDisplayAttribute) is EditorDisplayAttribute editorDisplayAttribute && !string.IsNullOrEmpty(editorDisplayAttribute.Name))
node.Text = $"{Utilities.Utils.GetPropertyNameUI(editorDisplayAttribute.Name)} ({Utilities.Utils.GetPropertyNameUI(editor.Values.Info.Name)})";
else
node.Text = Utilities.Utils.GetPropertyNameUI(editor.Values.Info.Name);
}
else if (sceneObject is Actor actor)
node.Text = $"{actor.Name} ({Utilities.Utils.GetPropertyNameUI(sceneObject.GetType().Name)})";
else
node.Text = Utilities.Utils.GetPropertyNameUI(sceneObject.GetType().Name);
}
// Array Item
else if (editor.ParentEditor is CollectionEditor)
@@ -268,7 +264,12 @@ namespace FlaxEditor.CustomEditors.Dedicated
// Common type
else if (editor.Values.Info != ScriptMemberInfo.Null)
{
node.Text = Utilities.Utils.GetPropertyNameUI(editor.Values.Info.Name);
if (editor.Values.GetAttributes().FirstOrDefault(x => x is EditorDisplayAttribute) is EditorDisplayAttribute editorDisplayAttribute
&& !string.IsNullOrEmpty(editorDisplayAttribute.Name)
&& !editorDisplayAttribute.Name.Contains("_inline"))
node.Text = $"{Utilities.Utils.GetPropertyNameUI(editorDisplayAttribute.Name)} ({Utilities.Utils.GetPropertyNameUI(editor.Values.Info.Name)})";
else
node.Text = Utilities.Utils.GetPropertyNameUI(editor.Values.Info.Name);
}
// Custom type
else if (editor.Values[0] != null)
@@ -316,7 +317,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
var childEditor = editor.ChildrenEditors[i];
// Special case for root actor transformation (can be applied only in Prefab editor, not in Level)
if (isActorEditorInLevel && childEditor.Values.Info.Name is "LocalPosition" or "LocalOrientation" or "LocalScale")
if (isActorEditorInLevel && childEditor.Values.Info.Name is "LocalPosition" or "LocalOrientation" or "LocalScale" or "Name")
continue;
var child = ProcessDiff(childEditor, !isScriptEditorWithRefValue);
@@ -361,13 +362,39 @@ namespace FlaxEditor.CustomEditors.Dedicated
return result;
}
private TreeNode CreateDiffTree(Actor actor, CustomEditorPresenter presenter, LayoutElementsContainer layout)
{
var actorNode = Editor.Instance.Scene.GetActorNode(actor);
ValueContainer vc = new ValueContainer(ScriptMemberInfo.Null);
vc.SetType(new ScriptType(actorNode.EditableObject.GetType()));
vc.Add(actorNode.EditableObject);
var editor = CustomEditorsUtil.CreateEditor(vc, null, false);
editor.Initialize(presenter, layout, vc);
var node = ProcessDiff(editor, false);
layout.ClearLayout();
foreach (var child in actor.Children)
{
var childNode = CreateDiffTree(child, presenter, layout);
if (childNode == null)
continue;
if (node == null)
node = CreateDiffNode(editor);
node.AddChild(childNode);
}
return node;
}
private void ViewChanges(Control target, Float2 targetLocation)
{
// Build a tree out of modified properties
var rootNode = ProcessDiff(this, false);
var thisActor = (Actor)Values[0];
var rootActor = thisActor.IsPrefabRoot ? thisActor : thisActor.GetPrefabRoot();
var presenter = new CustomEditorPresenter(null);
var layout = new CustomElementsContainer<ContainerControl>();
var rootNode = CreateDiffTree(rootActor, presenter, layout);
// Skip if no changes detected
if (rootNode == null || rootNode.ChildrenCount == 0)
if (rootNode == null)
{
var cm1 = new ContextMenu();
cm1.AddButton("No changes detected");

View File

@@ -28,7 +28,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
_infoLabel = playbackGroup.Label(string.Empty).Label;
_infoLabel.AutoHeight = true;
var grid = playbackGroup.CustomContainer<UniformGridPanel>();
var grid = playbackGroup.UniformGrid();
var gridControl = grid.CustomControl;
gridControl.ClipChildren = false;
gridControl.Height = Button.DefaultHeight;

View File

@@ -59,7 +59,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
var paintValue = new ReadOnlyValueContainer(new ScriptType(typeof(ClothPaintingGizmoMode)), _gizmoMode);
paintGroup.Object(paintValue);
{
var grid = paintGroup.CustomContainer<UniformGridPanel>();
var grid = paintGroup.UniformGrid();
var gridControl = grid.CustomControl;
gridControl.ClipChildren = false;
gridControl.Height = Button.DefaultHeight;

View File

@@ -92,12 +92,14 @@ namespace FlaxEditor.CustomEditors.Dedicated
// Update add button
var update = group.Button("Update").Button;
group.Space(0);
update.TooltipText = "Refreshes the dashboard statistics";
update.Height = 16.0f;
update.Clicked += RebuildLayout;
// New locale add button
var addLocale = group.Button("Add Locale...").Button;
group.Space(0);
addLocale.TooltipText = "Shows a locale picker and creates new localization for it with not translated string tables";
addLocale.Height = 16.0f;
addLocale.ButtonClicked += delegate(Button button)
@@ -167,12 +169,14 @@ namespace FlaxEditor.CustomEditors.Dedicated
// Export button
var exportLocalization = group.Button("Export...").Button;
group.Space(0);
exportLocalization.TooltipText = "Exports the localization strings into .pot file for translation";
exportLocalization.Height = 16.0f;
exportLocalization.Clicked += () => Export(tableEntries, allKeys);
// Find localized strings in code button
var findStringsCode = group.Button("Find localized strings in code").Button;
group.Space(0);
findStringsCode.TooltipText = "Searches for localized string usage in inside a project source files";
findStringsCode.Height = 16.0f;
findStringsCode.Clicked += delegate

View File

@@ -54,7 +54,8 @@ public class ModelPrefabEditor : GenericEditor
}
// Creates the import path UI
Utilities.Utils.CreateImportPathUI(layout, modelPrefab.ImportPath, false);
var group = layout.Group("Import Path");
Utilities.Utils.CreateImportPathUI(group, modelPrefab.ImportPath);
var button = layout.Button("Reimport", "Reimports the source asset as prefab.");
_reimportButton = button.Button;

View File

@@ -92,7 +92,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
_infoLabel = playbackGroup.Label(string.Empty).Label;
_infoLabel.AutoHeight = true;
var grid = playbackGroup.CustomContainer<UniformGridPanel>();
var grid = playbackGroup.UniformGrid();
var gridControl = grid.CustomControl;
gridControl.ClipChildren = false;
gridControl.Height = Button.DefaultHeight;

View File

@@ -39,7 +39,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
if (ragdoll.Parent is AnimatedModel animatedModel && animatedModel.SkinnedModel)
{
// Builder
var grid = editorGroup.CustomContainer<UniformGridPanel>();
var grid = editorGroup.UniformGrid();
var gridControl = grid.CustomControl;
gridControl.ClipChildren = false;
gridControl.Height = Button.DefaultHeight;
@@ -53,7 +53,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
if (Presenter.Owner != null)
{
// Selection
var grid = editorGroup.CustomContainer<UniformGridPanel>();
var grid = editorGroup.UniformGrid();
var gridControl = grid.CustomControl;
gridControl.ClipChildren = false;
gridControl.Height = Button.DefaultHeight;

View File

@@ -1,6 +1,7 @@
// Copyright (c) Wojciech Figat. All rights reserved.
using System.Collections.Generic;
using System.Reflection.Emit;
using FlaxEditor.CustomEditors.GUI;
using FlaxEngine;
using FlaxEngine.GUI;
@@ -93,8 +94,10 @@ namespace FlaxEditor.CustomEditors.Dedicated
// Add info box
if (IsSingleObject && Values[0] is RigidBody && Editor.IsPlayMode)
{
_infoLabel = layout.Label(string.Empty).Label;
var group = layout.Group("Info");
_infoLabel = group.Label(string.Empty).Label;
_infoLabel.AutoHeight = true;
_infoLabel.Margin = new Margin(3);
}
}
}

View File

@@ -28,7 +28,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
_infoLabel = playbackGroup.Label(string.Empty).Label;
_infoLabel.AutoHeight = true;
var grid = playbackGroup.CustomContainer<UniformGridPanel>();
var grid = playbackGroup.UniformGrid();
var gridControl = grid.CustomControl;
gridControl.ClipChildren = false;
gridControl.Height = Button.DefaultHeight;

View File

@@ -682,7 +682,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
private CustomElementsContainer<UniformGridPanel> UniformGridTwoByOne(LayoutElementsContainer cont)
{
var grid = cont.CustomContainer<UniformGridPanel>();
var grid = cont.UniformGrid();
grid.CustomControl.SlotsHorizontally = 2;
grid.CustomControl.SlotsVertically = 1;
grid.CustomControl.SlotPadding = Margin.Zero;

View File

@@ -41,13 +41,9 @@ namespace FlaxEditor.CustomEditors.Editors
public override void Initialize(LayoutElementsContainer layout)
{
base.Initialize(layout);
if (XElement.ValueBox.Parent is UniformGridPanel ug)
{
ug.Height += 2;
ug.SlotSpacing = new Float2(4);
ug.SlotPadding = new Margin(0, 0, 1, 1);
}
CheckLayout(ug);
// Override colors
var back = FlaxEngine.GUI.Style.Current.TextBoxBackground;
@@ -75,11 +71,7 @@ namespace FlaxEditor.CustomEditors.Editors
base.Initialize(layout);
if (XElement.ValueBox.Parent is UniformGridPanel ug)
{
ug.Height += 2;
ug.SlotSpacing = new Float2(4);
ug.SlotPadding = new Margin(0, 0, 1, 1);
}
CheckLayout(ug);
// Override colors
var back = FlaxEngine.GUI.Style.Current.TextBoxBackground;
@@ -136,13 +128,9 @@ namespace FlaxEditor.CustomEditors.Editors
menu.AddButton("Link", ToggleLink).LinkTooltip("Links scale components for uniform scaling");
};
}
if (XElement.ValueBox.Parent is UniformGridPanel ug)
{
ug.Height += 2;
ug.SlotSpacing = new Float2(4);
ug.SlotPadding = new Margin(0, 0, 1, 1);
}
CheckLayout(ug);
// Override colors
var back = FlaxEngine.GUI.Style.Current.TextBoxBackground;
@@ -203,5 +191,13 @@ namespace FlaxEditor.CustomEditors.Editors
_linkButton.TooltipText = LinkValues ? "Unlinks scale components from uniform scaling" : "Links scale components for uniform scaling";
}
}
private static void CheckLayout(UniformGridPanel ug)
{
// Enlarge to fix border visibility
ug.Height += 2;
ug.SlotSpacing += new Float2(2);
ug.SlotPadding += new Margin(0, 0, 1, 1);
}
}
}

View File

@@ -642,10 +642,10 @@ namespace FlaxEditor.CustomEditors.Editors
if (_canResize && !_readOnly)
{
var panel = dragArea.HorizontalPanel();
panel.Panel.Size = new Float2(0, 20);
panel.Panel.Margin = new Margin(2);
panel.Panel.Size = new Float2(0, 18);
panel.Panel.Margin = new Margin(0, 0, Utilities.Constants.UIMargin, 0);
var removeButton = panel.Button("-", "Remove last item");
var removeButton = panel.Button("-", "Remove the last item");
removeButton.Button.Size = new Float2(16, 16);
removeButton.Button.Enabled = size > _minCount;
removeButton.Button.AnchorPreset = AnchorPresets.TopRight;
@@ -656,7 +656,7 @@ namespace FlaxEditor.CustomEditors.Editors
Resize(Count - 1);
};
var addButton = panel.Button("+", "Add new item");
var addButton = panel.Button("+", "Add a new item");
addButton.Button.Size = new Float2(16, 16);
addButton.Button.Enabled = (!NotNullItems || size > 0) && size < _maxCount;
addButton.Button.AnchorPreset = AnchorPresets.TopRight;

View File

@@ -27,7 +27,7 @@ namespace FlaxEditor.CustomEditors.Editors
/// <inheritdoc />
public override void Initialize(LayoutElementsContainer layout)
{
float trackBallSize = 80.0f;
float trackBallSize = 100f;
float margin = 4.0f;
// Panel
@@ -50,7 +50,7 @@ namespace FlaxEditor.CustomEditors.Editors
// Scale editor
{
var grid = masterPanel.CustomContainer<UniformGridPanel>();
var grid = masterPanel.UniformGrid();
var gridControl = grid.CustomControl;
gridControl.SlotPadding = new Margin(4, 2, 2, 2);
gridControl.ClipChildren = false;

View File

@@ -46,7 +46,7 @@ namespace FlaxEditor.CustomEditors.Editors
/// <inheritdoc />
public override void Initialize(LayoutElementsContainer layout)
{
var grid = layout.CustomContainer<UniformGridPanel>();
var grid = layout.UniformGrid();
var gridControl = grid.CustomControl;
gridControl.ClipChildren = false;
gridControl.Height = TextBox.DefaultHeight;

View File

@@ -42,7 +42,7 @@ namespace FlaxEditor.CustomEditors.Editors
/// <inheritdoc />
public override void Initialize(LayoutElementsContainer layout)
{
var grid = layout.CustomContainer<UniformGridPanel>();
var grid = layout.UniformGrid();
var gridControl = grid.CustomControl;
gridControl.ClipChildren = false;
gridControl.Height = TextBox.DefaultHeight;
@@ -131,7 +131,7 @@ namespace FlaxEditor.CustomEditors.Editors
/// <inheritdoc />
public override void Initialize(LayoutElementsContainer layout)
{
var grid = layout.CustomContainer<UniformGridPanel>();
var grid = layout.UniformGrid();
var gridControl = grid.CustomControl;
gridControl.ClipChildren = false;
gridControl.Height = TextBox.DefaultHeight;
@@ -220,7 +220,7 @@ namespace FlaxEditor.CustomEditors.Editors
/// <inheritdoc />
public override void Initialize(LayoutElementsContainer layout)
{
var grid = layout.CustomContainer<UniformGridPanel>();
var grid = layout.UniformGrid();
var gridControl = grid.CustomControl;
gridControl.ClipChildren = false;
gridControl.Height = TextBox.DefaultHeight;

View File

@@ -82,7 +82,7 @@ namespace FlaxEditor.CustomEditors.Editors
/// <inheritdoc />
public override void Initialize(LayoutElementsContainer layout)
{
var grid = layout.CustomContainer<UniformGridPanel>();
var grid = layout.UniformGrid();
var gridControl = grid.CustomControl;
gridControl.ClipChildren = false;
gridControl.Height = TextBox.DefaultHeight;
@@ -469,7 +469,7 @@ namespace FlaxEditor.CustomEditors.Editors
/// <inheritdoc />
public override void Initialize(LayoutElementsContainer layout)
{
var grid = layout.CustomContainer<UniformGridPanel>();
var grid = layout.UniformGrid();
var gridControl = grid.CustomControl;
gridControl.ClipChildren = false;
gridControl.Height = TextBox.DefaultHeight;
@@ -783,7 +783,7 @@ namespace FlaxEditor.CustomEditors.Editors
/// <inheritdoc />
public override void Initialize(LayoutElementsContainer layout)
{
var grid = layout.CustomContainer<UniformGridPanel>();
var grid = layout.UniformGrid();
var gridControl = grid.CustomControl;
gridControl.ClipChildren = false;
gridControl.Height = TextBox.DefaultHeight;

View File

@@ -52,7 +52,7 @@ namespace FlaxEditor.CustomEditors.Editors
/// <inheritdoc />
public override void Initialize(LayoutElementsContainer layout)
{
var grid = layout.CustomContainer<UniformGridPanel>();
var grid = layout.UniformGrid();
var gridControl = grid.CustomControl;
gridControl.ClipChildren = false;
gridControl.Height = TextBox.DefaultHeight;
@@ -163,7 +163,7 @@ namespace FlaxEditor.CustomEditors.Editors
/// <inheritdoc />
public override void Initialize(LayoutElementsContainer layout)
{
var grid = layout.CustomContainer<UniformGridPanel>();
var grid = layout.UniformGrid();
var gridControl = grid.CustomControl;
gridControl.ClipChildren = false;
gridControl.Height = TextBox.DefaultHeight;
@@ -274,7 +274,7 @@ namespace FlaxEditor.CustomEditors.Editors
/// <inheritdoc />
public override void Initialize(LayoutElementsContainer layout)
{
var grid = layout.CustomContainer<UniformGridPanel>();
var grid = layout.UniformGrid();
var gridControl = grid.CustomControl;
gridControl.ClipChildren = false;
gridControl.Height = TextBox.DefaultHeight;

View File

@@ -39,7 +39,7 @@ namespace FlaxEditor.CustomEditors.Editors
/// <inheritdoc />
public override void Initialize(LayoutElementsContainer layout)
{
var grid = layout.CustomContainer<UniformGridPanel>();
var grid = layout.UniformGrid();
var gridControl = grid.CustomControl;
gridControl.ClipChildren = false;
gridControl.Height = TextBox.DefaultHeight;

View File

@@ -22,7 +22,8 @@ namespace FlaxEditor.CustomEditors.Elements
ArrowImageClosed = new SpriteBrush(Style.Current.ArrowRight),
ArrowImageOpened = new SpriteBrush(Style.Current.ArrowDown),
EnableDropDownIcon = true,
ItemsMargin = new Margin(7, 7, 3, 3),
ItemsMargin = new Margin(Utilities.Constants.UIMargin),
ItemsSpacing = Utilities.Constants.UIMargin,
HeaderHeight = 18.0f,
EnableContainmentLines = true,
};

View File

@@ -20,13 +20,6 @@ namespace FlaxEditor.CustomEditors.GUI
/// </summary>
public const int SplitterSize = 2;
/// <summary>
/// The splitter margin (in pixels).
/// </summary>
public const int SplitterMargin = 4;
private const int SplitterSizeHalf = SplitterSize / 2;
private PropertiesListElement _element;
private float _splitterValue;
private Rectangle _splitterRect;
@@ -65,16 +58,18 @@ namespace FlaxEditor.CustomEditors.GUI
/// <param name="element">The element.</param>
public PropertiesList(PropertiesListElement element)
{
ClipChildren = false;
_element = element;
_splitterValue = 0.4f;
BottomMargin = TopMargin = RightMargin = SplitterMargin;
Margin = new Margin();
Spacing = Utilities.Constants.UIMargin;
UpdateSplitRect();
}
private void UpdateSplitRect()
{
_splitterRect = new Rectangle(Mathf.Clamp(_splitterValue * Width - SplitterSizeHalf, 0.0f, Width), 0, SplitterSize, Height);
LeftMargin = _splitterValue * Width + SplitterMargin;
_splitterRect = new Rectangle(Mathf.Clamp(_splitterValue * Width - SplitterSize * 0.5f, 0.0f, Width), 0, SplitterSize, Height);
LeftMargin = _splitterValue * Width + _spacing;
}
private void StartTracking()
@@ -222,23 +217,33 @@ namespace FlaxEditor.CustomEditors.GUI
/// <inheritdoc />
protected override void PerformLayoutAfterChildren()
{
// Sort controls from up to down into two columns: one for labels and one for the rest of the stuff
// Place non-label controls from top to down
float y = _margin.Top;
float w = Width - _margin.Width;
bool firstItem = true;
for (int i = 0; i < _children.Count; i++)
{
Control c = _children[i];
if (!(c is PropertyNameLabel))
{
var h = c.Height;
c.Bounds = new Rectangle(_margin.Left, y + _spacing, w, h);
var rect = new Rectangle(_margin.Left, y, w, c.Height);
if (c.Visible)
{
if (firstItem)
firstItem = false;
else
rect.Y += _spacing;
}
else if (!firstItem)
rect.Y += _spacing;
c.Bounds = rect;
if (c.Visible)
y = c.Bottom;
}
}
y += _margin.Bottom;
// Place labels accordingly to their respective controls placement
float namesWidth = _splitterValue * Width;
int count = _element.Labels.Count;
float[] yStarts = new float[count + 1];
@@ -271,7 +276,9 @@ namespace FlaxEditor.CustomEditors.GUI
{
var label = _element.Labels[i];
var rect = new Rectangle(0, yStarts[i] + 1, namesWidth, yStarts[i + 1] - yStarts[i] - 2);
var rect = new Rectangle(0, yStarts[i], namesWidth, yStarts[i + 1] - yStarts[i]);
if (i != count - 1)
rect.Height -= _spacing;
//label.Parent = this;
label.Bounds = rect;
}

View File

@@ -202,6 +202,17 @@ namespace FlaxEditor.CustomEditors
return element;
}
/// <summary>
/// Adds new uniform grid control.
/// </summary>
/// <returns>The created element.</returns>
public CustomElementsContainer<UniformGridPanel> UniformGrid()
{
var grid = CustomContainer<UniformGridPanel>();
grid.CustomControl.SlotSpacing = new Float2(Utilities.Constants.UIMargin);
return grid;
}
/// <summary>
/// Adds new custom element.
/// </summary>

View File

@@ -1031,6 +1031,8 @@ namespace FlaxEditor
{
Internal_GetEditorBoxWithChildren(FlaxEngine.Object.GetUnmanagedPtr(actor), out var box);
BoundingSphere.FromBox(ref box, out sphere);
if (sphere == BoundingSphere.Empty)
sphere = new BoundingSphere(actor.Position, sphere.Radius);
sphere.Radius = Math.Max(sphere.Radius, 15.0f);
}
else

View File

@@ -611,6 +611,16 @@ namespace FlaxEditor.GUI
OnClickItem(focusedItem);
return true;
}
else
{
// Select first item if no item is focused (most likely to be the best result), saves the user from pressing arrow down first
var visibleItems = GetVisibleItems();
if (visibleItems.Count > 0)
{
OnClickItem(visibleItems[0]);
return true;
}
}
break;
}

View File

@@ -47,6 +47,7 @@ namespace FlaxEditor.GUI.Tabs
if (EnabledInHierarchy && Tab.Enabled)
{
Tabs.SelectedTab = Tab;
Tab.PerformLayout(true);
Tabs.Focus();
}
return true;

View File

@@ -40,6 +40,7 @@ namespace FlaxEditor.GUI.Tree
private readonly bool _supportMultiSelect;
private Margin _margin;
private bool _autoSize = true;
private bool _deferLayoutUpdate = false;
/// <summary>
/// The TreeNode that is being dragged over. This could have a value when not dragging.
@@ -66,6 +67,11 @@ namespace FlaxEditor.GUI.Tree
/// Gets the first selected node or null.
/// </summary>
public TreeNode SelectedNode => Selection.Count > 0 ? Selection[0] : null;
/// <summary>
/// Allow nodes to Draw the root tree line.
/// </summary>
public bool DrawRootTreeLine = true;
/// <summary>
/// Gets or sets the margin for the child tree nodes.
@@ -353,9 +359,25 @@ namespace FlaxEditor.GUI.Tree
BulkSelectUpdateExpanded(false);
}
/// <inheritdoc />
public override void PerformLayout(bool force = false)
{
if (_isLayoutLocked && !force)
return;
// In case the tree was fully expanded or collapsed along its children, avoid calculating the layout multiple times for each child
_deferLayoutUpdate = true;
}
/// <inheritdoc />
public override void Update(float deltaTime)
{
if (_deferLayoutUpdate)
{
base.PerformLayout();
_deferLayoutUpdate = false;
}
var node = SelectedNode;
// Check if has focus and if any node is focused and it isn't a root

View File

@@ -760,20 +760,21 @@ namespace FlaxEditor.GUI.Tree
// Show tree guidelines
if (Editor.Instance.Options.Options.Interface.ShowTreeLines)
{
TreeNode parentNode = Parent as TreeNode;
ContainerControl parent = Parent;
TreeNode parentNode = parent as TreeNode;
bool thisNodeIsLast = false;
while (parentNode != null && parentNode != ParentTree.Children[0])
while (parentNode != null && (parentNode != tree.Children[0] || tree.DrawRootTreeLine))
{
float bottomOffset = 0;
float topOffset = 0;
if (Parent == parentNode && this == Parent.Children[0])
if (parent == parentNode && this == parent.Children[0])
topOffset = 2;
if (thisNodeIsLast && parentNode.Children.Count == 1)
bottomOffset = topOffset != 0 ? 4 : 2;
if (Parent == parentNode && this == Parent.Children[Parent.Children.Count - 1] && !_opened)
if (parent == parentNode && this == parent.Children[^1] && !_opened)
{
thisNodeIsLast = true;
bottomOffset = topOffset != 0 ? 4 : 2;
@@ -784,6 +785,8 @@ namespace FlaxEditor.GUI.Tree
if (_iconCollaped.IsValid)
leftOffset += 18;
var lineRect1 = new Rectangle(parentNode.TextRect.Left - leftOffset, parentNode.HeaderRect.Top + topOffset, 1, parentNode.HeaderRect.Height - bottomOffset);
if (HasAnyVisibleChild && CustomArrowRect.HasValue && CustomArrowRect.Value.Intersects(lineRect1))
lineRect1 = Rectangle.Empty; // Skip drawing line if it's overlapping the arrow rectangle
Render2D.FillRectangle(lineRect1, isSelected ? style.ForegroundGrey : style.LightBackground);
parentNode = parentNode.Parent as TreeNode;
}

View File

@@ -255,12 +255,17 @@ namespace FlaxEditor.Modules
// When applying changes to prefab from actor in level ignore it's root transformation (see ActorEditor.ProcessDiff)
var originalTransform = instance.LocalTransform;
var originalName = instance.Name;
if (instance.IsPrefabRoot && instance.HasScene)
{
instance.LocalTransform = prefab.GetDefaultInstance().Transform;
instance.Name = prefab.GetDefaultInstance().Name;
}
// Call backend
var failed = PrefabManager.Internal_ApplyAll(FlaxEngine.Object.GetUnmanagedPtr(instance));
instance.LocalTransform = originalTransform;
instance.Name = originalName;
if (failed)
throw new Exception("Failed to apply the prefab. See log to learn more.");

View File

@@ -5,6 +5,7 @@ using System.Collections.Generic;
using System.Linq;
using FlaxEditor.Actions;
using FlaxEditor.SceneGraph;
using FlaxEditor.SceneGraph.Actors;
using FlaxEngine;
namespace FlaxEditor.Modules
@@ -561,7 +562,8 @@ namespace FlaxEditor.Modules
public void CreateParentForSelectedActors()
{
List<SceneGraphNode> selection = Editor.SceneEditing.Selection;
var actors = selection.Where(x => x is ActorNode).Select(x => ((ActorNode)x).Actor);
// Get Actors but skip scene node
var actors = selection.Where(x => x is ActorNode and not SceneNode).Select(x => ((ActorNode)x).Actor);
var actorsCount = actors.Count();
if (actorsCount == 0)
return;

View File

@@ -306,19 +306,21 @@ namespace FlaxEditor.Modules
public override void OnPlayEnd()
{
var gameWin = Editor.Windows.GameWin;
switch (gameWin.FocusOnPlayOption)
if (gameWin != null)
{
case Options.InterfaceOptions.PlayModeFocus.None: break;
case Options.InterfaceOptions.PlayModeFocus.GameWindow: break;
case Options.InterfaceOptions.PlayModeFocus.GameWindowThenRestore:
if (_previousWindow != null && !_previousWindow.IsDisposing)
switch (gameWin.FocusOnPlayOption)
{
if (!Editor.Windows.GameWin.ParentDockPanel.ContainsTab(_previousWindow))
break;
_previousWindow.Focus();
case Options.InterfaceOptions.PlayModeFocus.None: break;
case Options.InterfaceOptions.PlayModeFocus.GameWindow: break;
case Options.InterfaceOptions.PlayModeFocus.GameWindowThenRestore:
if (_previousWindow != null && !_previousWindow.IsDisposing)
{
if (!Editor.Windows.GameWin.ParentDockPanel.ContainsTab(_previousWindow))
break;
_previousWindow.Focus();
}
break;
}
break;
}
Editor.UI.UncheckPauseButton();

View File

@@ -621,19 +621,19 @@ namespace FlaxEditor.Modules
MenuWindow = MainMenu.AddButton("Window");
cm = MenuWindow.ContextMenu;
cm.VisibleChanged += OnMenuWindowVisibleChanged;
cm.AddButton("Content", Editor.Windows.ContentWin.FocusOrShow);
cm.AddButton("Scene", Editor.Windows.SceneWin.FocusOrShow);
cm.AddButton("Toolbox", Editor.Windows.ToolboxWin.FocusOrShow);
cm.AddButton("Properties", Editor.Windows.PropertiesWin.FocusOrShow);
cm.AddButton("Game", Editor.Windows.GameWin.FocusOrShow);
cm.AddButton("Editor", Editor.Windows.EditWin.FocusOrShow);
cm.AddButton("Debug Log", Editor.Windows.DebugLogWin.FocusOrShow);
cm.AddButton("Output Log", Editor.Windows.OutputLogWin.FocusOrShow);
cm.AddButton("Graphics Quality", Editor.Windows.GraphicsQualityWin.FocusOrShow);
cm.AddButton("Game Cooker", Editor.Windows.GameCookerWin.FocusOrShow);
cm.AddButton("Content", inputOptions.ContentWindow,Editor.Windows.ContentWin.FocusOrShow);
cm.AddButton("Scene", inputOptions.SceneWindow, Editor.Windows.SceneWin.FocusOrShow);
cm.AddButton("Toolbox", inputOptions.ToolboxWindow, Editor.Windows.ToolboxWin.FocusOrShow);
cm.AddButton("Properties", inputOptions.PropertiesWindow, Editor.Windows.PropertiesWin.FocusOrShow);
cm.AddButton("Game", inputOptions.GameWindow, Editor.Windows.GameWin.FocusOrShow);
cm.AddButton("Editor", inputOptions.EditorWindow, Editor.Windows.EditWin.FocusOrShow);
cm.AddButton("Debug Log", inputOptions.DebugLogWindow, Editor.Windows.DebugLogWin.FocusOrShow);
cm.AddButton("Output Log", inputOptions.OutputLogWindow, Editor.Windows.OutputLogWin.FocusOrShow);
cm.AddButton("Graphics Quality", inputOptions.GraphicsQualityWindow, Editor.Windows.GraphicsQualityWin.FocusOrShow);
cm.AddButton("Game Cooker", inputOptions.GameCookerWindow, Editor.Windows.GameCookerWin.FocusOrShow);
cm.AddButton("Profiler", inputOptions.ProfilerWindow, Editor.Windows.ProfilerWin.FocusOrShow);
cm.AddButton("Content Search", Editor.ContentFinding.ShowSearch);
cm.AddButton("Visual Script Debugger", Editor.Windows.VisualScriptDebuggerWin.FocusOrShow);
cm.AddButton("Content Search", inputOptions.ContentSearchWindow, Editor.ContentFinding.ShowSearch);
cm.AddButton("Visual Script Debugger", inputOptions.VisualScriptDebuggerWindow, Editor.Windows.VisualScriptDebuggerWin.FocusOrShow);
cm.AddSeparator();
cm.AddButton("Save window layout", Editor.Windows.SaveLayout);
_menuWindowApplyWindowLayout = cm.AddChildMenu("Window layouts");

View File

@@ -33,6 +33,25 @@ namespace FlaxEditor.Options
OpenPrefab,
}
/// <summary>
/// Shortcut availability in play mode.
/// </summary>
public enum PlayModeShortcutAvailability
{
/// <summary>
/// None of the window shortcuts will be available in play mode.
/// </summary>
None,
/// <summary>
/// Only the profiler window shortcut will be available in play mode.
/// </summary>
ProfilerOnly,
/// <summary>
/// All window shortcuts will be available in play mode.
/// </summary>
All,
}
/// <summary>
/// Input editor options data container.
/// </summary>
@@ -40,6 +59,16 @@ namespace FlaxEditor.Options
[HideInEditor]
public sealed class InputOptions
{
/// <summary>
/// Gets a value based on the current settings that indicates wether window shortcuts will be avaliable during play mode.
/// </summary>
public static bool WindowShortcutsAvaliable => !Editor.IsPlayMode || Editor.Instance.Options.Options.Input.PlayModeWindowShortcutAvaliability == PlayModeShortcutAvailability.All;
/// <summary>
/// Gets a value based on the current settings that indicates wether the profiler window shortcut will be avaliable during play mode.
/// </summary>
public static bool ProfilerShortcutAvaliable => WindowShortcutsAvaliable || Editor.Instance.Options.Options.Input.PlayModeWindowShortcutAvaliability == PlayModeShortcutAvailability.ProfilerOnly;
#region Common
[DefaultValue(typeof(InputBinding), "Ctrl+S")]
@@ -230,9 +259,9 @@ namespace FlaxEditor.Options
#region Profiler
[DefaultValue(typeof(InputBinding), "None")]
[DefaultValue(typeof(InputBinding), "Ctrl+Alpha7")]
[EditorDisplay("Profiler", "Open Profiler Window"), EditorOrder(630)]
public InputBinding ProfilerWindow = new InputBinding(KeyboardKeys.None);
public InputBinding ProfilerWindow = new InputBinding(KeyboardKeys.Alpha7, KeyboardKeys.Control);
[DefaultValue(typeof(InputBinding), "None")]
[EditorDisplay("Profiler", "Start/Stop Profiler"), EditorOrder(631)]
@@ -356,24 +385,267 @@ namespace FlaxEditor.Options
#endregion
#region Debug Views
[DefaultValue(typeof(InputBinding), "Alt+Alpha4")]
[EditorDisplay("Debug Views"), EditorOrder(2000)]
public InputBinding Default = new InputBinding(KeyboardKeys.Alpha4, KeyboardKeys.Alt);
[DefaultValue(typeof(InputBinding), "Alt+Alpha3")]
[EditorDisplay("Debug Views"), EditorOrder(2010)]
public InputBinding Unlit = new InputBinding(KeyboardKeys.Alpha3, KeyboardKeys.Alt);
[DefaultValue(typeof(InputBinding), "None")]
[EditorDisplay("Debug Views"), EditorOrder(2020)]
public InputBinding NoPostFX = new InputBinding(KeyboardKeys.None);
[DefaultValue(typeof(InputBinding), "Alt+Alpha2")]
[EditorDisplay("Debug Views"), EditorOrder(2030)]
public InputBinding Wireframe = new InputBinding(KeyboardKeys.Alpha2, KeyboardKeys.Alt);
[DefaultValue(typeof(InputBinding), "Alt+Alpha5")]
[EditorDisplay("Debug Views"), EditorOrder(2040)]
public InputBinding LightBuffer = new InputBinding(KeyboardKeys.Alpha5, KeyboardKeys.Alt);
[DefaultValue(typeof(InputBinding), "None")]
[EditorDisplay("Debug Views"), EditorOrder(2050)]
public InputBinding ReflectionsBuffer = new InputBinding(KeyboardKeys.None);
[DefaultValue(typeof(InputBinding), "None")]
[EditorDisplay("Debug Views"), EditorOrder(2060)]
public InputBinding DepthBuffer = new InputBinding(KeyboardKeys.None);
[DefaultValue(typeof(InputBinding), "None")]
[EditorDisplay("Debug Views"), EditorOrder(2070)]
public InputBinding MotionVectors = new InputBinding(KeyboardKeys.None);
[DefaultValue(typeof(InputBinding), "None")]
[EditorDisplay("Debug Views"), EditorOrder(2080)]
public InputBinding LightmapUVDensity = new InputBinding(KeyboardKeys.None);
[DefaultValue(typeof(InputBinding), "None")]
[EditorDisplay("Debug Views"), EditorOrder(2090)]
public InputBinding VertexColors = new InputBinding(KeyboardKeys.None);
[DefaultValue(typeof(InputBinding), "Alt+Alpha1")]
[EditorDisplay("Debug Views"), EditorOrder(2100)]
public InputBinding PhysicsColliders = new InputBinding(KeyboardKeys.Alpha1, KeyboardKeys.Alt);
[DefaultValue(typeof(InputBinding), "None")]
[EditorDisplay("Debug Views"), EditorOrder(2110)]
public InputBinding LODPreview = new InputBinding(KeyboardKeys.None);
[DefaultValue(typeof(InputBinding), "None")]
[EditorDisplay("Debug Views"), EditorOrder(2120)]
public InputBinding MaterialComplexity = new InputBinding(KeyboardKeys.None);
[DefaultValue(typeof(InputBinding), "None")]
[EditorDisplay("Debug Views"), EditorOrder(2130)]
public InputBinding QuadOverdraw = new InputBinding(KeyboardKeys.None);
[DefaultValue(typeof(InputBinding), "None")]
[EditorDisplay("Debug Views"), EditorOrder(2140)]
public InputBinding GloablSDF = new InputBinding(KeyboardKeys.None);
[DefaultValue(typeof(InputBinding), "None")]
[EditorDisplay("Debug Views"), EditorOrder(2150)]
public InputBinding GlobalSurfaceAtlas = new InputBinding(KeyboardKeys.None);
[DefaultValue(typeof(InputBinding), "None")]
[EditorDisplay("Debug Views"), EditorOrder(2160)]
public InputBinding GlobalIllumination = new InputBinding(KeyboardKeys.None);
#endregion
#region View Flags
[DefaultValue(typeof(InputBinding), "None")]
[EditorDisplay("View Flags"), EditorOrder(3000)]
public InputBinding AntiAliasing = new InputBinding(KeyboardKeys.None);
[DefaultValue(typeof(InputBinding), "None")]
[EditorDisplay("View Flags"), EditorOrder(3010)]
public InputBinding Shadows = new InputBinding(KeyboardKeys.None);
[DefaultValue(typeof(InputBinding), "Shift+Ctrl+Alpha7")]
[EditorDisplay("View Flags"), EditorOrder(3020)]
public InputBinding EditorSprites = new InputBinding(KeyboardKeys.Alpha7, KeyboardKeys.Control, KeyboardKeys.Shift);
[DefaultValue(typeof(InputBinding), "None")]
[EditorDisplay("View Flags"), EditorOrder(3030)]
public InputBinding Reflections = new InputBinding(KeyboardKeys.None);
[DefaultValue(typeof(InputBinding), "None")]
[EditorDisplay("View Flags"), EditorOrder(3040)]
public InputBinding ScreenSpaceReflections = new InputBinding(KeyboardKeys.None);
[DefaultValue(typeof(InputBinding), "None")]
[EditorDisplay("View Flags"), EditorOrder(3050)]
public InputBinding AmbientOcclusion = new InputBinding(KeyboardKeys.None);
[DefaultValue(typeof(InputBinding), "Shift+Ctrl+Alpha6")]
[EditorDisplay("View Flags", "Global Illumination"), EditorOrder(3060)]
public InputBinding GlobalIlluminationViewFlag = new InputBinding(KeyboardKeys.Alpha6, KeyboardKeys.Control, KeyboardKeys.Shift);
[DefaultValue(typeof(InputBinding), "None")]
[EditorDisplay("View Flags"), EditorOrder(3070)]
public InputBinding DirectionalLights = new InputBinding(KeyboardKeys.None);
[DefaultValue(typeof(InputBinding), "None")]
[EditorDisplay("View Flags"), EditorOrder(3080)]
public InputBinding PointLights = new InputBinding(KeyboardKeys.None);
[DefaultValue(typeof(InputBinding), "None")]
[EditorDisplay("View Flags"), EditorOrder(3090)]
public InputBinding SpotLights = new InputBinding(KeyboardKeys.None);
[DefaultValue(typeof(InputBinding), "None")]
[EditorDisplay("View Flags"), EditorOrder(3100)]
public InputBinding SkyLights = new InputBinding(KeyboardKeys.None);
[DefaultValue(typeof(InputBinding), "None")]
[EditorDisplay("View Flags"), EditorOrder(3110)]
public InputBinding Sky = new InputBinding(KeyboardKeys.None);
[DefaultValue(typeof(InputBinding), "None")]
[EditorDisplay("View Flags"), EditorOrder(3120)]
public InputBinding Fog = new InputBinding(KeyboardKeys.None);
[DefaultValue(typeof(InputBinding), "None")]
[EditorDisplay("View Flags"), EditorOrder(3130)]
public InputBinding SpecularLight = new InputBinding(KeyboardKeys.None);
[DefaultValue(typeof(InputBinding), "None")]
[EditorDisplay("View Flags"), EditorOrder(3140)]
public InputBinding Decals = new InputBinding(KeyboardKeys.None);
[DefaultValue(typeof(InputBinding), "Shift+Ctrl+Alpha3")]
[EditorDisplay("View Flags"), EditorOrder(3150)]
public InputBinding CustomPostProcess = new InputBinding(KeyboardKeys.Alpha3, KeyboardKeys.Control, KeyboardKeys.Shift);
[DefaultValue(typeof(InputBinding), "None")]
[EditorDisplay("View Flags"), EditorOrder(3160)]
public InputBinding Bloom = new InputBinding(KeyboardKeys.None);
[DefaultValue(typeof(InputBinding), "None")]
[EditorDisplay("View Flags"), EditorOrder(3170)]
public InputBinding ToneMapping = new InputBinding(KeyboardKeys.None);
[DefaultValue(typeof(InputBinding), "Shift+Ctrl+Alpha2")]
[EditorDisplay("View Flags"), EditorOrder(3180)]
public InputBinding EyeAdaptation = new InputBinding(KeyboardKeys.Alpha2, KeyboardKeys.Control, KeyboardKeys.Shift);
[DefaultValue(typeof(InputBinding), "None")]
[EditorDisplay("View Flags"), EditorOrder(3190)]
public InputBinding CameraArtifacts = new InputBinding(KeyboardKeys.None);
[DefaultValue(typeof(InputBinding), "None")]
[EditorDisplay("View Flags"), EditorOrder(3200)]
public InputBinding LensFlares = new InputBinding(KeyboardKeys.None);
[DefaultValue(typeof(InputBinding), "None")]
[EditorDisplay("View Flags"), EditorOrder(3210)]
public InputBinding DepthOfField = new InputBinding(KeyboardKeys.None);
[DefaultValue(typeof(InputBinding), "None")]
[EditorDisplay("View Flags"), EditorOrder(3220)]
public InputBinding MotionBlur = new InputBinding(KeyboardKeys.None);
[DefaultValue(typeof(InputBinding), "None")]
[EditorDisplay("View Flags"), EditorOrder(3230)]
public InputBinding ContactShadows = new InputBinding(KeyboardKeys.None);
[DefaultValue(typeof(InputBinding), "Shift+Ctrl+Alpha1")]
[EditorDisplay("View Flags"), EditorOrder(3240)]
public InputBinding PhysicsDebug = new InputBinding(KeyboardKeys.Alpha1, KeyboardKeys.Control, KeyboardKeys.Shift);
[DefaultValue(typeof(InputBinding), "Shift+Ctrl+Alpha5")]
[EditorDisplay("View Flags"), EditorOrder(3250)]
public InputBinding LightsDebug = new InputBinding(KeyboardKeys.Alpha5, KeyboardKeys.Control, KeyboardKeys.Shift);
[DefaultValue(typeof(InputBinding), "Shift+Ctrl+Alpha4")]
[EditorDisplay("View Flags"), EditorOrder(3260)]
public InputBinding DebugDraw = new InputBinding(KeyboardKeys.Alpha4, KeyboardKeys.Control, KeyboardKeys.Shift);
#endregion
#region Interface
[DefaultValue(typeof(InputBinding), "Ctrl+W")]
[EditorDisplay("Interface"), EditorOrder(2000)]
[EditorDisplay("Interface"), EditorOrder(3500)]
public InputBinding CloseTab = new InputBinding(KeyboardKeys.W, KeyboardKeys.Control);
[DefaultValue(typeof(InputBinding), "Ctrl+Tab")]
[EditorDisplay("Interface"), EditorOrder(2010)]
[EditorDisplay("Interface"), EditorOrder(3510)]
public InputBinding NextTab = new InputBinding(KeyboardKeys.Tab, KeyboardKeys.Control);
[DefaultValue(typeof(InputBinding), "Shift+Ctrl+Tab")]
[EditorDisplay("Interface"), EditorOrder(2020)]
[EditorDisplay("Interface"), EditorOrder(3520)]
public InputBinding PreviousTab = new InputBinding(KeyboardKeys.Tab, KeyboardKeys.Control, KeyboardKeys.Shift);
[DefaultValue(SceneNodeDoubleClick.Expand)]
[EditorDisplay("Interface"), EditorOrder(2030)]
[EditorDisplay("Interface"), EditorOrder(3530)]
public SceneNodeDoubleClick DoubleClickSceneNode = SceneNodeDoubleClick.Expand;
#endregion
#region Windows
/// <summary>
/// Gets or sets a value indicating what window shortcuts will be available during play mode.
/// </summary>
[DefaultValue(PlayModeShortcutAvailability.ProfilerOnly)]
[EditorDisplay("Windows", "Avaliability in Play Mode"), EditorOrder(3000)]
public PlayModeShortcutAvailability PlayModeWindowShortcutAvaliability { get; set; } = PlayModeShortcutAvailability.ProfilerOnly;
[DefaultValue(typeof(InputBinding), "Ctrl+Alpha5")]
[EditorDisplay("Windows"), EditorOrder(3010)]
public InputBinding ContentWindow = new InputBinding(KeyboardKeys.Alpha5, KeyboardKeys.Control);
[DefaultValue(typeof(InputBinding), "Ctrl+Alpha4")]
[EditorDisplay("Windows"), EditorOrder(3020)]
public InputBinding SceneWindow = new InputBinding(KeyboardKeys.Alpha4, KeyboardKeys.Control);
[DefaultValue(typeof(InputBinding), "None")]
[EditorDisplay("Windows"), EditorOrder(3030)]
public InputBinding ToolboxWindow = new InputBinding(KeyboardKeys.None);
[DefaultValue(typeof(InputBinding), "Ctrl+Alpha3")]
[EditorDisplay("Windows"), EditorOrder(3040)]
public InputBinding PropertiesWindow = new InputBinding(KeyboardKeys.Alpha3, KeyboardKeys.Control);
[DefaultValue(typeof(InputBinding), "Ctrl+Alpha2")]
[EditorDisplay("Windows"), EditorOrder(3050)]
public InputBinding GameWindow = new InputBinding(KeyboardKeys.Alpha2, KeyboardKeys.Control);
[DefaultValue(typeof(InputBinding), "Ctrl+Alpha1")]
[EditorDisplay("Windows"), EditorOrder(3060)]
public InputBinding EditorWindow = new InputBinding(KeyboardKeys.Alpha1, KeyboardKeys.Control);
[DefaultValue(typeof(InputBinding), "None")]
[EditorDisplay("Windows"), EditorOrder(3070)]
public InputBinding DebugLogWindow = new InputBinding(KeyboardKeys.None);
[DefaultValue(typeof(InputBinding), "None")]
[EditorDisplay("Windows"), EditorOrder(3080)]
public InputBinding OutputLogWindow = new InputBinding(KeyboardKeys.C, KeyboardKeys.Control, KeyboardKeys.Shift);
[DefaultValue(typeof(InputBinding), "None")]
[EditorDisplay("Windows"), EditorOrder(3090)]
public InputBinding GraphicsQualityWindow = new InputBinding(KeyboardKeys.None);
[DefaultValue(typeof(InputBinding), "None")]
[EditorDisplay("Windows"), EditorOrder(4000)]
public InputBinding GameCookerWindow = new InputBinding(KeyboardKeys.None);
[DefaultValue(typeof(InputBinding), "None")]
[EditorDisplay("Windows"), EditorOrder(4010)]
public InputBinding ContentSearchWindow = new InputBinding(KeyboardKeys.None);
[DefaultValue(typeof(InputBinding), "None")]
[EditorDisplay("Windows"), EditorOrder(4020)]
public InputBinding VisualScriptDebuggerWindow = new InputBinding(KeyboardKeys.None);
#endregion
}
}

View File

@@ -28,7 +28,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
_infoLabel = playbackGroup.Label(string.Empty).Label;
_infoLabel.AutoHeight = true;
var grid = playbackGroup.CustomContainer<UniformGridPanel>();
var grid = layout.UniformGrid();
var gridControl = grid.CustomControl;
gridControl.ClipChildren = false;
gridControl.Height = Button.DefaultHeight;

View File

@@ -320,7 +320,7 @@ namespace FlaxEditor.SceneGraph.GUI
if (noFilter && actor != null)
{
// Pick the correct id when inside a prefab window.
var id = actor.HasPrefabLink && actor.Scene.Scene == null ? actor.PrefabObjectID : actor.ID;
var id = actor.HasPrefabLink && actor.Scene == null ? actor.PrefabObjectID : actor.ID;
isExpanded = Editor.Instance.ProjectCache.IsExpandedActor(ref id);
}

View File

@@ -573,11 +573,11 @@ namespace FlaxEditor.Surface.Archetypes
"Blend animation poses (with additive mode)" +
"\n" +
"\nNote: " +
"\nOrder of nodes matters, because Additive animation is appplayed on top of curent frame." +
"\nThe order of the nodes is important, because additive animation is applied on top of current frame." +
"\n" +
"\nTip for blender users:" +
"\nInside NLA the the order is bottom (first node in flax) to the top (last node in flax)" +
"\nu need to place it in this order to get correct resoults",
"\nInside NLA the the order is bottom (first node in flax) to the top (last node in flax)." +
"\nYou need to place animations in this order to get correct results.",
Flags = NodeFlags.AnimGraph,
Size = new Float2(170, 80),
DefaultValues = new object[]

View File

@@ -607,14 +607,14 @@ namespace FlaxEditor.Surface.Archetypes
Title = "Terrain Layer Weight",
Description = "Terrain layer weight mask used for blending terrain layers",
Flags = NodeFlags.MaterialGraph,
Size = new Float2(220, 30),
Size = new Float2(200, 30),
DefaultValues = new object[]
{
0,
},
Elements = new[]
{
NodeElementArchetype.Factory.ComboBox(0, 0, 70.0f, 0, LayersAndTagsSettings.GetCurrentTerrainLayers()),
NodeElementArchetype.Factory.ComboBox(0, 0, 175.0f, 0, LayersAndTagsSettings.GetCurrentTerrainLayers()),
NodeElementArchetype.Factory.Output(0, "", typeof(float), 0),
}
},

View File

@@ -409,7 +409,7 @@ namespace FlaxEditor.Surface
/// <summary>
/// Called after adding the control to the surface after paste.
/// </summary>
/// <param name="idsMapping">The nodes IDs mapping (original node ID to pasted node ID). Can be sued to update internal node's data after paste operation from the original data.</param>
/// <param name="idsMapping">The nodes IDs mapping (original node ID to pasted node ID). Can be used to update internal node's data after paste operation from the original data.</param>
public virtual void OnPasted(System.Collections.Generic.Dictionary<uint, uint> idsMapping)
{
}

View File

@@ -369,24 +369,14 @@ namespace FlaxEditor.Surface
}
// Change scale (disable scaling during selecting nodes)
if (IsMouseOver && !_leftMouseDown && !IsPrimaryMenuOpened)
if (IsMouseOver && !_leftMouseDown && !_rightMouseDown && !IsPrimaryMenuOpened)
{
var nextViewScale = ViewScale + delta * 0.1f;
if (delta > 0 && !_rightMouseDown)
{
// Scale towards mouse when zooming in
var nextCenterPosition = ViewPosition + location / ViewScale;
ViewScale = nextViewScale;
ViewPosition = nextCenterPosition - (location / ViewScale);
}
else
{
// Scale while keeping center position when zooming out or when dragging view
var viewCenter = ViewCenterPosition;
ViewScale = nextViewScale;
ViewCenterPosition = viewCenter;
}
// Scale towards/ away from mouse when zooming in/ out
var nextCenterPosition = ViewPosition + location / ViewScale;
ViewScale = nextViewScale;
ViewPosition = nextCenterPosition - (location / ViewScale);
return true;
}

View File

@@ -20,5 +20,7 @@ namespace FlaxEditor.Utilities
#else
public const string ShowInExplorer = "Show in explorer";
#endif
public const float UIMargin = 3.0f;
}
}

View File

@@ -402,7 +402,7 @@ namespace FlaxEditor.Utilities
/// <summary>
/// Creates an Import path ui that show the asset import path and adds a button to show the folder in the file system.
/// </summary>
/// <param name="parentLayout">The parent layout container.</param>
/// <param name="parentLayout">The parent layout element.</param>
/// <param name="assetItem">The asset item to get the import path of.</param>
public static void CreateImportPathUI(CustomEditors.LayoutElementsContainer parentLayout, Content.BinaryAssetItem assetItem)
{
@@ -413,21 +413,16 @@ namespace FlaxEditor.Utilities
/// <summary>
/// Creates an Import path ui that show the import path and adds a button to show the folder in the file system.
/// </summary>
/// <param name="parentLayout">The parent layout container.</param>
/// <param name="parentLayout">The parent layout element.</param>
/// <param name="path">The import path.</param>
/// <param name="useInitialSpacing">Whether to use an initial layout space of 5 for separation.</param>
public static void CreateImportPathUI(CustomEditors.LayoutElementsContainer parentLayout, string path, bool useInitialSpacing = true)
public static void CreateImportPathUI(CustomEditors.LayoutElementsContainer parentLayout, string path)
{
if (!string.IsNullOrEmpty(path))
{
if (useInitialSpacing)
parentLayout.Space(5);
parentLayout.Label("Import Path:").Label.TooltipText = "Source asset path (can be relative or absolute to the project)";
var textBox = parentLayout.TextBox().TextBox;
textBox.TooltipText = "Path is not editable here.";
textBox.TooltipText = "Source asset path. Can be relative or absolute to the project. Path is not editable here.";
textBox.IsReadOnly = true;
textBox.Text = path;
parentLayout.Space(2);
var button = parentLayout.Button(Constants.ShowInExplorer).Button;
button.Clicked += () => FileSystem.ShowFileExplorer(Path.GetDirectoryName(path));
}
@@ -1505,7 +1500,6 @@ namespace FlaxEditor.Utilities
inputActions.Add(options => options.BuildNav, Editor.Instance.BuildNavMesh);
inputActions.Add(options => options.BuildSDF, Editor.Instance.BuildAllMeshesSDF);
inputActions.Add(options => options.TakeScreenshot, Editor.Instance.Windows.TakeScreenshot);
inputActions.Add(options => options.ProfilerWindow, () => Editor.Instance.Windows.ProfilerWin.FocusOrShow());
#if USE_PROFILER
inputActions.Add(options => options.ProfilerStartStop, () =>
{

View File

@@ -916,7 +916,7 @@ namespace FlaxEditor.Viewport
for (int i = 0; i < ViewFlagsValues.Length; i++)
{
var v = ViewFlagsValues[i];
var button = viewFlags.AddButton(v.Name);
var button = viewFlags.AddButton(v.Name, v.InputBinding.ToString());
button.CloseMenuOnClick = false;
button.Tag = v.Mode;
}
@@ -965,7 +965,7 @@ namespace FlaxEditor.Viewport
}
else
{
var button = debugView.AddButton(v.Name);
var button = debugView.AddButton(v.Name, v.InputBinding.ToString());
button.CloseMenuOnClick = false;
button.Tag = v.Mode;
}
@@ -1011,16 +1011,64 @@ namespace FlaxEditor.Viewport
#endregion View mode widget
}
// Viewpoints
InputActions.Add(options => options.ViewpointTop, () => OrientViewport(Quaternion.Euler(CameraViewpointValues.First(vp => vp.Name == "Top").Orientation)));
InputActions.Add(options => options.ViewpointBottom, () => OrientViewport(Quaternion.Euler(CameraViewpointValues.First(vp => vp.Name == "Bottom").Orientation)));
InputActions.Add(options => options.ViewpointFront, () => OrientViewport(Quaternion.Euler(CameraViewpointValues.First(vp => vp.Name == "Front").Orientation)));
InputActions.Add(options => options.ViewpointBack, () => OrientViewport(Quaternion.Euler(CameraViewpointValues.First(vp => vp.Name == "Back").Orientation)));
InputActions.Add(options => options.ViewpointRight, () => OrientViewport(Quaternion.Euler(CameraViewpointValues.First(vp => vp.Name == "Right").Orientation)));
InputActions.Add(options => options.ViewpointLeft, () => OrientViewport(Quaternion.Euler(CameraViewpointValues.First(vp => vp.Name == "Left").Orientation)));
// Editor camera
InputActions.Add(options => options.CameraToggleRotation, () => _isVirtualMouseRightDown = !_isVirtualMouseRightDown);
InputActions.Add(options => options.CameraIncreaseMoveSpeed, () => AdjustCameraMoveSpeed(1));
InputActions.Add(options => options.CameraDecreaseMoveSpeed, () => AdjustCameraMoveSpeed(-1));
InputActions.Add(options => options.ToggleOrthographic, () => OnOrthographicModeToggled(null));
// Debug views
InputActions.Add(options => options.Default, () => Task.ViewMode = ViewMode.Default);
InputActions.Add(options => options.Unlit, () => Task.ViewMode = ViewMode.Unlit);
InputActions.Add(options => options.NoPostFX, () => Task.ViewMode = ViewMode.NoPostFx);
InputActions.Add(options => options.Wireframe, () => Task.ViewMode = ViewMode.Wireframe);
InputActions.Add(options => options.LightBuffer, () => Task.ViewMode = ViewMode.LightBuffer);
InputActions.Add(options => options.ReflectionsBuffer, () => Task.ViewMode = ViewMode.Reflections);
InputActions.Add(options => options.DepthBuffer, () => Task.ViewMode = ViewMode.Depth);
InputActions.Add(options => options.MotionVectors, () => Task.ViewMode = ViewMode.MotionVectors);
InputActions.Add(options => options.LightmapUVDensity, () => Task.ViewMode = ViewMode.LightmapUVsDensity);
InputActions.Add(options => options.VertexColors, () => Task.ViewMode = ViewMode.VertexColors);
InputActions.Add(options => options.PhysicsColliders, () => Task.ViewMode = ViewMode.PhysicsColliders);
InputActions.Add(options => options.LODPreview, () => Task.ViewMode = ViewMode.LODPreview);
InputActions.Add(options => options.MaterialComplexity, () => Task.ViewMode = ViewMode.MaterialComplexity);
InputActions.Add(options => options.QuadOverdraw, () => Task.ViewMode = ViewMode.QuadOverdraw);
InputActions.Add(options => options.GloablSDF, () => Task.ViewMode = ViewMode.GlobalSDF);
InputActions.Add(options => options.GlobalSurfaceAtlas, () => Task.ViewMode = ViewMode.GlobalSurfaceAtlas);
InputActions.Add(options => options.GlobalIllumination, () => Task.ViewMode = ViewMode.GlobalIllumination);
// View flags
InputActions.Add(options => options.AntiAliasing, () => Task.ViewFlags ^= ViewFlags.AntiAliasing);
InputActions.Add(options => options.Shadows, () => Task.ViewFlags ^= ViewFlags.Shadows);
InputActions.Add(options => options.EditorSprites, () => Task.ViewFlags ^= ViewFlags.EditorSprites);
InputActions.Add(options => options.Reflections, () => Task.ViewFlags ^= ViewFlags.Reflections);
InputActions.Add(options => options.ScreenSpaceReflections, () => Task.ViewFlags ^= ViewFlags.SSR);
InputActions.Add(options => options.AmbientOcclusion, () => Task.ViewFlags ^= ViewFlags.AO);
InputActions.Add(options => options.GlobalIllumination, () => Task.ViewFlags ^= ViewFlags.GI);
InputActions.Add(options => options.DirectionalLights, () => Task.ViewFlags ^= ViewFlags.DirectionalLights);
InputActions.Add(options => options.PointLights, () => Task.ViewFlags ^= ViewFlags.PointLights);
InputActions.Add(options => options.SpotLights, () => Task.ViewFlags ^= ViewFlags.SpotLights);
InputActions.Add(options => options.SkyLights, () => Task.ViewFlags ^= ViewFlags.SkyLights);
InputActions.Add(options => options.Sky, () => Task.ViewFlags ^= ViewFlags.Sky);
InputActions.Add(options => options.Fog, () => Task.ViewFlags ^= ViewFlags.Fog);
InputActions.Add(options => options.SpecularLight, () => Task.ViewFlags ^= ViewFlags.SpecularLight);
InputActions.Add(options => options.Decals, () => Task.ViewFlags ^= ViewFlags.Decals);
InputActions.Add(options => options.CustomPostProcess, () => Task.ViewFlags ^= ViewFlags.CustomPostProcess);
InputActions.Add(options => options.Bloom, () => Task.ViewFlags ^= ViewFlags.Bloom);
InputActions.Add(options => options.ToneMapping, () => Task.ViewFlags ^= ViewFlags.ToneMapping);
InputActions.Add(options => options.EyeAdaptation, () => Task.ViewFlags ^= ViewFlags.EyeAdaptation);
InputActions.Add(options => options.CameraArtifacts, () => Task.ViewFlags ^= ViewFlags.CameraArtifacts);
InputActions.Add(options => options.LensFlares, () => Task.ViewFlags ^= ViewFlags.LensFlares);
InputActions.Add(options => options.DepthOfField, () => Task.ViewFlags ^= ViewFlags.DepthOfField);
InputActions.Add(options => options.MotionBlur, () => Task.ViewFlags ^= ViewFlags.MotionBlur);
InputActions.Add(options => options.ContactShadows, () => Task.ViewFlags ^= ViewFlags.ContactShadows);
InputActions.Add(options => options.PhysicsDebug, () => Task.ViewFlags ^= ViewFlags.PhysicsDebug);
InputActions.Add(options => options.LightsDebug, () => Task.ViewFlags ^= ViewFlags.LightsDebug);
InputActions.Add(options => options.DebugDraw, () => Task.ViewFlags ^= ViewFlags.DebugDraw);
// Link for task event
task.Begin += OnRenderBegin;
@@ -1965,8 +2013,17 @@ namespace FlaxEditor.Viewport
{
public readonly string Name;
public readonly ViewMode Mode;
public readonly InputBinding InputBinding;
public readonly ViewModeOptions[] Options;
public ViewModeOptions(ViewMode mode, string name, InputBinding inputBinding)
{
Mode = mode;
Name = name;
InputBinding = inputBinding;
Options = null;
}
public ViewModeOptions(ViewMode mode, string name)
{
Mode = mode;
@@ -1984,13 +2041,13 @@ namespace FlaxEditor.Viewport
private static readonly ViewModeOptions[] ViewModeValues =
{
new ViewModeOptions(ViewMode.Default, "Default"),
new ViewModeOptions(ViewMode.Unlit, "Unlit"),
new ViewModeOptions(ViewMode.NoPostFx, "No PostFx"),
new ViewModeOptions(ViewMode.Wireframe, "Wireframe"),
new ViewModeOptions(ViewMode.LightBuffer, "Light Buffer"),
new ViewModeOptions(ViewMode.Reflections, "Reflections Buffer"),
new ViewModeOptions(ViewMode.Depth, "Depth Buffer"),
new ViewModeOptions(ViewMode.Default, "Default", Editor.Instance.Options.Options.Input.Default),
new ViewModeOptions(ViewMode.Unlit, "Unlit", Editor.Instance.Options.Options.Input.Unlit),
new ViewModeOptions(ViewMode.NoPostFx, "No PostFx", Editor.Instance.Options.Options.Input.NoPostFX),
new ViewModeOptions(ViewMode.Wireframe, "Wireframe", Editor.Instance.Options.Options.Input.Wireframe),
new ViewModeOptions(ViewMode.LightBuffer, "Light Buffer", Editor.Instance.Options.Options.Input.LightBuffer),
new ViewModeOptions(ViewMode.Reflections, "Reflections Buffer", Editor.Instance.Options.Options.Input.ReflectionsBuffer),
new ViewModeOptions(ViewMode.Depth, "Depth Buffer", Editor.Instance.Options.Options.Input.DepthBuffer),
new ViewModeOptions("GBuffer", new[]
{
new ViewModeOptions(ViewMode.Diffuse, "Diffuse"),
@@ -2004,16 +2061,16 @@ namespace FlaxEditor.Viewport
new ViewModeOptions(ViewMode.Normals, "Normals"),
new ViewModeOptions(ViewMode.AmbientOcclusion, "Ambient Occlusion"),
}),
new ViewModeOptions(ViewMode.MotionVectors, "Motion Vectors"),
new ViewModeOptions(ViewMode.LightmapUVsDensity, "Lightmap UVs Density"),
new ViewModeOptions(ViewMode.VertexColors, "Vertex Colors"),
new ViewModeOptions(ViewMode.PhysicsColliders, "Physics Colliders"),
new ViewModeOptions(ViewMode.LODPreview, "LOD Preview"),
new ViewModeOptions(ViewMode.MaterialComplexity, "Material Complexity"),
new ViewModeOptions(ViewMode.QuadOverdraw, "Quad Overdraw"),
new ViewModeOptions(ViewMode.GlobalSDF, "Global SDF"),
new ViewModeOptions(ViewMode.GlobalSurfaceAtlas, "Global Surface Atlas"),
new ViewModeOptions(ViewMode.GlobalIllumination, "Global Illumination"),
new ViewModeOptions(ViewMode.MotionVectors, "Motion Vectors", Editor.Instance.Options.Options.Input.MotionVectors),
new ViewModeOptions(ViewMode.LightmapUVsDensity, "Lightmap UVs Density", Editor.Instance.Options.Options.Input.LightmapUVDensity),
new ViewModeOptions(ViewMode.VertexColors, "Vertex Colors", Editor.Instance.Options.Options.Input.VertexColors),
new ViewModeOptions(ViewMode.PhysicsColliders, "Physics Colliders", Editor.Instance.Options.Options.Input.PhysicsColliders),
new ViewModeOptions(ViewMode.LODPreview, "LOD Preview", Editor.Instance.Options.Options.Input.LODPreview),
new ViewModeOptions(ViewMode.MaterialComplexity, "Material Complexity", Editor.Instance.Options.Options.Input.MaterialComplexity),
new ViewModeOptions(ViewMode.QuadOverdraw, "Quad Overdraw", Editor.Instance.Options.Options.Input.QuadOverdraw),
new ViewModeOptions(ViewMode.GlobalSDF, "Global SDF", Editor.Instance.Options.Options.Input.GloablSDF),
new ViewModeOptions(ViewMode.GlobalSurfaceAtlas, "Global Surface Atlas", Editor.Instance.Options.Options.Input.GlobalSurfaceAtlas),
new ViewModeOptions(ViewMode.GlobalIllumination, "Global Illumination", Editor.Instance.Options.Options.Input.GlobalIllumination),
};
private void WidgetViewModeShowHideClicked(ContextMenuButton button)
@@ -2046,43 +2103,45 @@ namespace FlaxEditor.Viewport
{
public readonly ViewFlags Mode;
public readonly string Name;
public readonly InputBinding InputBinding;
public ViewFlagOptions(ViewFlags mode, string name)
public ViewFlagOptions(ViewFlags mode, string name, InputBinding inputBinding)
{
Mode = mode;
Name = name;
InputBinding = inputBinding;
}
}
private static readonly ViewFlagOptions[] ViewFlagsValues =
{
new ViewFlagOptions(ViewFlags.AntiAliasing, "Anti Aliasing"),
new ViewFlagOptions(ViewFlags.Shadows, "Shadows"),
new ViewFlagOptions(ViewFlags.EditorSprites, "Editor Sprites"),
new ViewFlagOptions(ViewFlags.Reflections, "Reflections"),
new ViewFlagOptions(ViewFlags.SSR, "Screen Space Reflections"),
new ViewFlagOptions(ViewFlags.AO, "Ambient Occlusion"),
new ViewFlagOptions(ViewFlags.GI, "Global Illumination"),
new ViewFlagOptions(ViewFlags.DirectionalLights, "Directional Lights"),
new ViewFlagOptions(ViewFlags.PointLights, "Point Lights"),
new ViewFlagOptions(ViewFlags.SpotLights, "Spot Lights"),
new ViewFlagOptions(ViewFlags.SkyLights, "Sky Lights"),
new ViewFlagOptions(ViewFlags.Sky, "Sky"),
new ViewFlagOptions(ViewFlags.Fog, "Fog"),
new ViewFlagOptions(ViewFlags.SpecularLight, "Specular Light"),
new ViewFlagOptions(ViewFlags.Decals, "Decals"),
new ViewFlagOptions(ViewFlags.CustomPostProcess, "Custom Post Process"),
new ViewFlagOptions(ViewFlags.Bloom, "Bloom"),
new ViewFlagOptions(ViewFlags.ToneMapping, "Tone Mapping"),
new ViewFlagOptions(ViewFlags.EyeAdaptation, "Eye Adaptation"),
new ViewFlagOptions(ViewFlags.CameraArtifacts, "Camera Artifacts"),
new ViewFlagOptions(ViewFlags.LensFlares, "Lens Flares"),
new ViewFlagOptions(ViewFlags.DepthOfField, "Depth of Field"),
new ViewFlagOptions(ViewFlags.MotionBlur, "Motion Blur"),
new ViewFlagOptions(ViewFlags.ContactShadows, "Contact Shadows"),
new ViewFlagOptions(ViewFlags.PhysicsDebug, "Physics Debug"),
new ViewFlagOptions(ViewFlags.LightsDebug, "Lights Debug"),
new ViewFlagOptions(ViewFlags.DebugDraw, "Debug Draw"),
new ViewFlagOptions(ViewFlags.AntiAliasing, "Anti Aliasing", Editor.Instance.Options.Options.Input.AntiAliasing),
new ViewFlagOptions(ViewFlags.Shadows, "Shadows", Editor.Instance.Options.Options.Input.Shadows),
new ViewFlagOptions(ViewFlags.EditorSprites, "Editor Sprites", Editor.Instance.Options.Options.Input.EditorSprites),
new ViewFlagOptions(ViewFlags.Reflections, "Reflections", Editor.Instance.Options.Options.Input.Reflections),
new ViewFlagOptions(ViewFlags.SSR, "Screen Space Reflections", Editor.Instance.Options.Options.Input.ScreenSpaceReflections),
new ViewFlagOptions(ViewFlags.AO, "Ambient Occlusion", Editor.Instance.Options.Options.Input.AmbientOcclusion),
new ViewFlagOptions(ViewFlags.GI, "Global Illumination", Editor.Instance.Options.Options.Input.GlobalIlluminationViewFlag),
new ViewFlagOptions(ViewFlags.DirectionalLights, "Directional Lights", Editor.Instance.Options.Options.Input.DirectionalLights),
new ViewFlagOptions(ViewFlags.PointLights, "Point Lights", Editor.Instance.Options.Options.Input.PointLights),
new ViewFlagOptions(ViewFlags.SpotLights, "Spot Lights", Editor.Instance.Options.Options.Input.SpotLights),
new ViewFlagOptions(ViewFlags.SkyLights, "Sky Lights", Editor.Instance.Options.Options.Input.SkyLights),
new ViewFlagOptions(ViewFlags.Sky, "Sky", Editor.Instance.Options.Options.Input.Sky),
new ViewFlagOptions(ViewFlags.Fog, "Fog", Editor.Instance.Options.Options.Input.Fog),
new ViewFlagOptions(ViewFlags.SpecularLight, "Specular Light", Editor.Instance.Options.Options.Input.SpecularLight),
new ViewFlagOptions(ViewFlags.Decals, "Decals", Editor.Instance.Options.Options.Input.Decals),
new ViewFlagOptions(ViewFlags.CustomPostProcess, "Custom Post Process", Editor.Instance.Options.Options.Input.CustomPostProcess),
new ViewFlagOptions(ViewFlags.Bloom, "Bloom", Editor.Instance.Options.Options.Input.Bloom),
new ViewFlagOptions(ViewFlags.ToneMapping, "Tone Mapping", Editor.Instance.Options.Options.Input.ToneMapping),
new ViewFlagOptions(ViewFlags.EyeAdaptation, "Eye Adaptation", Editor.Instance.Options.Options.Input.EyeAdaptation),
new ViewFlagOptions(ViewFlags.CameraArtifacts, "Camera Artifacts", Editor.Instance.Options.Options.Input.CameraArtifacts),
new ViewFlagOptions(ViewFlags.LensFlares, "Lens Flares", Editor.Instance.Options.Options.Input.LensFlares),
new ViewFlagOptions(ViewFlags.DepthOfField, "Depth of Field", Editor.Instance.Options.Options.Input.DepthOfField),
new ViewFlagOptions(ViewFlags.MotionBlur, "Motion Blur", Editor.Instance.Options.Options.Input.MotionBlur),
new ViewFlagOptions(ViewFlags.ContactShadows, "Contact Shadows", Editor.Instance.Options.Options.Input.ContactShadows),
new ViewFlagOptions(ViewFlags.PhysicsDebug, "Physics Debug", Editor.Instance.Options.Options.Input.PhysicsDebug),
new ViewFlagOptions(ViewFlags.LightsDebug, "Lights Debug", Editor.Instance.Options.Options.Input.LightsDebug),
new ViewFlagOptions(ViewFlags.DebugDraw, "Debug Draw", Editor.Instance.Options.Options.Input.DebugDraw),
};
private void WidgetViewFlagsShowHide(Control cm)

View File

@@ -185,7 +185,7 @@ namespace FlaxEditor.Viewport.Previews
{
UseTimeScale = false,
UpdateWhenOffscreen = true,
BoundsScale = 100.0f,
BoundsScale = 1.0f,
UpdateMode = AnimatedModel.AnimationUpdateMode.Manual,
};
Task.AddCustomActor(_previewModel);

View File

@@ -231,7 +231,8 @@ namespace FlaxEditor.Windows.Assets
group.Object(importSettingsValues);
// Creates the import path UI
Utilities.Utils.CreateImportPathUI(layout, proxy.Window.Item as BinaryAssetItem);
group = layout.Group("Import Path");
Utilities.Utils.CreateImportPathUI(group, proxy.Window.Item as BinaryAssetItem);
layout.Space(5);
var reimportButton = layout.Button("Reimport");

View File

@@ -6,6 +6,7 @@ using FlaxEditor.Content.Import;
using FlaxEditor.CustomEditors;
using FlaxEditor.CustomEditors.Editors;
using FlaxEditor.GUI;
using FlaxEditor.Scripting;
using FlaxEditor.Viewport.Previews;
using FlaxEngine;
using FlaxEngine.GUI;
@@ -76,7 +77,8 @@ namespace FlaxEditor.Windows.Assets
{
public override void Initialize(LayoutElementsContainer layout)
{
var window = ((PropertiesProxy)Values[0])._window;
var proxy = ((PropertiesProxy)Values[0]);
var window = proxy._window;
if (window == null)
{
layout.Label("Loading...", TextAlignment.Center);
@@ -101,7 +103,8 @@ namespace FlaxEditor.Windows.Assets
base.Initialize(layout);
// Creates the import path UI
Utilities.Utils.CreateImportPathUI(layout, window.Item as BinaryAssetItem);
var pathGroup = layout.Group("Import Path");
Utilities.Utils.CreateImportPathUI(pathGroup, window.Item as BinaryAssetItem);
layout.Space(5);
var reimportButton = layout.Button("Reimport");

View File

@@ -635,5 +635,11 @@ namespace FlaxEditor.Windows.Assets
public void Select(List<SceneGraphNode> nodes)
{
}
/// <inheritdoc />
public List<SceneGraphNode> Selection => new List<SceneGraphNode>();
/// <inheritdoc />
public bool LockSelection { get; set; }
}
}

View File

@@ -102,6 +102,8 @@ namespace FlaxEditor.Windows.Assets
private class CookData : CreateFileEntry
{
public override bool CanBeCreated => true;
public PropertiesProxy Proxy;
public CollisionDataType Type;
public ModelBase Model;

View File

@@ -55,10 +55,11 @@ namespace FlaxEditor.Windows.Assets
base.Initialize(layout);
// Creates the import path UI
Utilities.Utils.CreateImportPathUI(layout, window.Item as BinaryAssetItem);
var pathGroup = layout.Group("Import Path");
Utilities.Utils.CreateImportPathUI(pathGroup, window.Item as BinaryAssetItem);
layout.Space(5);
var reimportButton = layout.Button("Reimport");
pathGroup.Space(5);
var reimportButton = pathGroup.Button("Reimport");
reimportButton.Button.Clicked += () => ((PropertiesProxy)Values[0]).Reimport();
}
}

View File

@@ -754,17 +754,17 @@ namespace FlaxEditor.Windows.Assets
if (Utilities.Utils.OnAssetProperties(layout, proxy.Asset))
return;
var group = layout.Group("Import Settings");
var importSettingsGroup = layout.Group("Import Settings");
var importSettingsField = typeof(ImportPropertiesProxyBase).GetField(nameof(ImportSettings), BindingFlags.NonPublic | BindingFlags.Instance);
var importSettingsValues = new ValueContainer(new ScriptMemberInfo(importSettingsField)) { proxy.ImportSettings };
group.Object(importSettingsValues);
importSettingsGroup.Object(importSettingsValues);
// Creates the import path UI
Utilities.Utils.CreateImportPathUI(layout, proxy.Window.Item as BinaryAssetItem);
var group = layout.Group("Import Path");
Utilities.Utils.CreateImportPathUI(group, proxy.Window.Item as BinaryAssetItem);
layout.Space(5);
var reimportButton = group.Button("Reimport");
var reimportButton = importSettingsGroup.Button("Reimport");
reimportButton.Button.Clicked += () => ((ImportPropertiesProxyBase)Values[0]).Reimport();
}
}

View File

@@ -114,7 +114,7 @@ namespace FlaxEditor.Windows.Assets
lodIndex.IntValue.Value = sdf.Texture != null ? sdf.LOD : 6;
_sdfModelLodIndex = lodIndex;
var buttons = group.CustomContainer<UniformGridPanel>();
var buttons = layout.UniformGrid();
var gridControl = buttons.CustomControl;
gridControl.ClipChildren = false;
gridControl.Height = Button.DefaultHeight;

View File

@@ -56,6 +56,7 @@ namespace FlaxEditor.Windows.Assets
public PrefabTree()
: base(true)
{
DrawRootTreeLine = false;
}
}

View File

@@ -51,7 +51,7 @@ namespace FlaxEditor.Windows.Assets
/// <param name="before">The selection before the change.</param>
public void OnSelectionChanged(SceneGraphNode[] before)
{
if (LockSelectedObjects)
if (LockSelection)
return;
Undo.AddAction(new SelectionChangeAction(before, Selection.ToArray(), OnSelectionUndo));

View File

@@ -78,7 +78,7 @@ namespace FlaxEditor.Windows.Assets
/// <summary>
/// Indication of if the prefab window selection is locked on specific objects.
/// </summary>
public bool LockSelectedObjects
public bool LockSelection
{
get => _lockSelection;
set
@@ -160,6 +160,7 @@ namespace FlaxEditor.Windows.Assets
AnchorPreset = AnchorPresets.HorizontalStretchMiddle,
Parent = headerPanel,
Bounds = new Rectangle(4, 4, headerPanel.Width - 8, 18),
TooltipText = "Search the prefab.\n\nYou can prefix your search with different search operators:\ns: -> Actor with script of type\na: -> Actor type\nc: -> Control type",
};
_searchBox.TextChanged += OnSearchBoxTextChanged;

View File

@@ -119,9 +119,10 @@ namespace FlaxEditor.Windows.Assets
}
base.Initialize(layout);
// Creates the import path UI
Utilities.Utils.CreateImportPathUI(layout, proxy._window.Item as BinaryAssetItem);
var group = layout.Group("Import Path");
Utilities.Utils.CreateImportPathUI(group, proxy._window.Item as BinaryAssetItem);
layout.Space(5);
var reimportButton = layout.Button("Reimport");

View File

@@ -143,7 +143,8 @@ namespace FlaxEditor.Windows.Assets
base.Initialize(layout);
// Creates the import path UI
Utilities.Utils.CreateImportPathUI(layout, proxy._window.Item as BinaryAssetItem);
var group = layout.Group("Import Path");
Utilities.Utils.CreateImportPathUI(group, proxy._window.Item as BinaryAssetItem);
// Reimport
layout.Space(5);

View File

@@ -413,7 +413,7 @@ namespace FlaxEditor.Windows.Assets
var group = layout.Group("Functions");
var nodes = window.VisjectSurface.Nodes;
var grid = group.CustomContainer<UniformGridPanel>();
var grid = layout.UniformGrid();
var gridControl = grid.CustomControl;
gridControl.ClipChildren = false;
gridControl.Height = Button.DefaultHeight;

View File

@@ -204,6 +204,7 @@ namespace FlaxEditor.Windows
// Content structure tree
_tree = new Tree(false)
{
DrawRootTreeLine = false,
Parent = _contentTreePanel,
};
_tree.SelectedChanged += OnTreeSelectionChanged;

View File

@@ -140,6 +140,7 @@ namespace FlaxEditor.Windows
: base(editor, true, ScrollBars.None)
{
Title = "Editor";
Icon = editor.Icons.Grid32;
// Create viewport
Viewport = new MainEditorGizmoViewport(editor)

View File

@@ -2,6 +2,7 @@
using System;
using FlaxEditor.Content;
using FlaxEditor.Options;
using FlaxEngine;
using FlaxEngine.GUI;
using DockWindow = FlaxEditor.GUI.Docking.DockWindow;
@@ -49,6 +50,73 @@ namespace FlaxEditor.Windows
}
});
// Set up editor window shortcuts
InputActions.Add(options => options.ContentWindow, () =>
{
if (InputOptions.WindowShortcutsAvaliable)
Editor.Windows.ContentWin.FocusOrShow();
});
InputActions.Add(options => options.SceneWindow, () =>
{
if (InputOptions.WindowShortcutsAvaliable)
Editor.Windows.SceneWin.FocusOrShow();
});
InputActions.Add(options => options.ToolboxWindow, () =>
{
if (InputOptions.WindowShortcutsAvaliable)
Editor.Windows.ToolboxWin.FocusOrShow();
});
InputActions.Add(options => options.PropertiesWindow, () =>
{
if (InputOptions.WindowShortcutsAvaliable)
Editor.Windows.PropertiesWin.FocusOrShow();
});
InputActions.Add(options => options.GameWindow, () =>
{
if (InputOptions.WindowShortcutsAvaliable)
Editor.Windows.GameWin.FocusOrShow();
});
InputActions.Add(options => options.EditorWindow, () =>
{
if (InputOptions.WindowShortcutsAvaliable)
Editor.Windows.EditWin.FocusOrShow();
});
InputActions.Add(options => options.DebugLogWindow, () =>
{
if (InputOptions.WindowShortcutsAvaliable)
Editor.Windows.DebugLogWin.FocusOrShow();
});
InputActions.Add(options => options.OutputLogWindow, () =>
{
if (InputOptions.WindowShortcutsAvaliable)
Editor.Windows.OutputLogWin.FocusOrShow();
});
InputActions.Add(options => options.GraphicsQualityWindow, () =>
{
if (InputOptions.WindowShortcutsAvaliable)
Editor.Windows.GraphicsQualityWin.FocusOrShow();
});
InputActions.Add(options => options.GameCookerWindow, () =>
{
if (InputOptions.WindowShortcutsAvaliable)
Editor.Windows.GameCookerWin.FocusOrShow();
});
InputActions.Add(options => options.ProfilerWindow, () =>
{
if (InputOptions.ProfilerShortcutAvaliable)
Editor.Windows.ProfilerWin.FocusOrShow();
});
InputActions.Add(options => options.ContentFinder, () =>
{
if (InputOptions.WindowShortcutsAvaliable)
Editor.ContentFinding.ShowSearch();
});
InputActions.Add(options => options.VisualScriptDebuggerWindow, () =>
{
if (InputOptions.WindowShortcutsAvaliable)
Editor.Windows.VisualScriptDebuggerWin.FocusOrShow();
});
// Register
Editor.Windows.OnWindowAdd(this);
}

View File

@@ -292,7 +292,7 @@ namespace FlaxEditor.Windows
private class GameRoot : UIEditorRoot
{
internal bool Editable = true;
public override bool EnableInputs => !Time.GamePaused && Editor.IsPlayMode && Editable;
public override bool EnableInputs => !Time.GamePaused && Editor.IsPlayMode;
public override bool EnableSelecting => (!Editor.IsPlayMode || Time.GamePaused) && Editable;
public override TransformGizmo TransformGizmo => Editor.Instance.MainTransformGizmo;
}
@@ -305,6 +305,7 @@ namespace FlaxEditor.Windows
: base(editor, true, ScrollBars.None)
{
Title = "Game";
Icon = editor.Icons.Play64;
AutoFocus = true;
var task = MainRenderTask.Instance;

View File

@@ -482,6 +482,7 @@ namespace FlaxEditor.Windows
: base(editor, true, ScrollBars.None)
{
Title = "Output Log";
Icon = editor.Icons.Info64;
ClipChildren = false;
FlaxEditor.Utilities.Utils.SetupCommonInputActions(this);
@@ -983,6 +984,10 @@ namespace FlaxEditor.Windows
var cachedOutputTargetViewOffset = _output.TargetViewOffset;
var isBottomScroll = _vScroll.Value >= _vScroll.Maximum - (_scrollSize * 2) || wasEmpty;
_output.Text = _textBuffer.ToString();
if (_hScroll.Maximum <= 0.0)
cachedOutputTargetViewOffset.X = 0;
if (_vScroll.Maximum <= 0.0)
cachedOutputTargetViewOffset.Y = 0;
_output.TargetViewOffset = cachedOutputTargetViewOffset;
_textBufferCount = _entries.Count;
if (!_vScroll.IsThumbClicked)

View File

@@ -492,7 +492,7 @@ namespace FlaxEditor.Windows.Profiler
{
break;
}
subEventsMemoryTotal += sub.ManagedMemoryAllocation + e.NativeMemoryAllocation;
subEventsMemoryTotal += sub.ManagedMemoryAllocation + sub.NativeMemoryAllocation;
}
string name = e.Name.Replace("::", ".");

View File

@@ -45,7 +45,7 @@ namespace FlaxEditor.Windows
/// <summary>
/// Indication of if the properties window is locked on specific objects.
/// </summary>
public bool LockObjects
public bool LockSelection
{
get => _lockObjects;
set
@@ -66,6 +66,7 @@ namespace FlaxEditor.Windows
: base(editor, true, ScrollBars.Vertical)
{
Title = "Properties";
Icon = editor.Icons.Build64;
AutoFocus = true;
Presenter = new CustomEditorPresenter(editor.Undo, null, this);
@@ -86,9 +87,9 @@ namespace FlaxEditor.Windows
if (Level.ScenesCount > 1)
return;
_actorScrollValues.Clear();
if (LockObjects)
if (LockSelection)
{
LockObjects = false;
LockSelection = false;
Presenter.Deselect();
}
}
@@ -121,7 +122,7 @@ namespace FlaxEditor.Windows
private void OnSelectionChanged()
{
if (LockObjects)
if (LockSelection)
return;
// Update selected objects

View File

@@ -47,6 +47,7 @@ namespace FlaxEditor.Windows
: base(editor, true, ScrollBars.None)
{
Title = "Scene";
Icon = editor.Icons.Globe32;
// Scene searching query input box
var headerPanel = new ContainerControl
@@ -83,6 +84,7 @@ namespace FlaxEditor.Windows
{
Margin = new Margin(0.0f, 0.0f, -16.0f, _sceneTreePanel.ScrollBarsSize), // Hide root node
IsScrollable = true,
DrawRootTreeLine = false,
};
_tree.AddChild(root.TreeNode);
_tree.SelectedChanged += Tree_OnSelectedChanged;

View File

@@ -455,6 +455,7 @@ namespace FlaxEditor.Windows
: base(editor, true, ScrollBars.None)
{
Title = "Toolbox";
Icon = editor.Icons.Toolbox96;
FlaxEditor.Utilities.Utils.SetupCommonInputActions(this);
}