Merge branch 'master' into 1.11

This commit is contained in:
Wojtek Figat
2025-06-05 18:03:17 +02:00
189 changed files with 4627 additions and 1426 deletions

View File

@@ -14,6 +14,7 @@ namespace FlaxEditor.Content.Create
/// <seealso cref="FlaxEditor.Content.Create.CreateFileEntry" />
public class PrefabCreateEntry : CreateFileEntry
{
/// <inheritdoc />
public override bool CanBeCreated => _options.RootActorType != null;
/// <summary>

View File

@@ -145,7 +145,7 @@ namespace FlaxEditor.Content.GUI
set
{
value = Mathf.Clamp(value, 0.3f, 3.0f);
if (!Mathf.NearEqual(value, _viewScale))
if (value != _viewScale)
{
_viewScale = value;
ViewScaleChanged?.Invoke();

View File

@@ -10,11 +10,9 @@ using FlaxEngine;
namespace FlaxEditor.Content
{
/// <summary>
/// Context proxy object for shader source files (represented by <see cref="ShaderSourceItem"/>).
/// Base class for shader source files.
/// </summary>
/// <seealso cref="FlaxEditor.Content.ContentProxy" />
[ContentContextMenu("New/Shader Source")]
public class ShaderSourceProxy : ContentProxy
public abstract class ShaderBaseProxy : ContentProxy
{
/// <inheritdoc />
public override bool CanCreate(ContentFolder targetLocation)
@@ -29,6 +27,21 @@ namespace FlaxEditor.Content
return targetLocation.ShortName == "Source" && prevTargetLocation.ShortName == "Shaders";
}
/// <inheritdoc />
public override EditorWindow Open(Editor editor, ContentItem item)
{
Editor.Instance.CodeEditing.OpenFile(item.Path);
return null;
}
}
/// <summary>
/// Context proxy object for shader source files (represented by <see cref="ShaderSourceItem"/>).
/// </summary>
/// <seealso cref="FlaxEditor.Content.ContentProxy" />
[ContentContextMenu("New/Shader Source (.shader)")]
public class ShaderSourceProxy : ShaderBaseProxy
{
/// <inheritdoc />
public override void Create(string outputPath, object arg)
{
@@ -44,13 +57,6 @@ namespace FlaxEditor.Content
File.WriteAllText(outputPath, shaderTemplate, Encoding.UTF8);
}
/// <inheritdoc />
public override EditorWindow Open(Editor editor, ContentItem item)
{
Editor.Instance.CodeEditing.OpenFile(item.Path);
return null;
}
/// <inheritdoc />
public override Color AccentColor => Color.FromRGB(0x7542f5);
@@ -66,4 +72,33 @@ namespace FlaxEditor.Content
return item is ShaderSourceItem;
}
}
/// <summary>
/// Context proxy object for shader header files.
/// </summary>
/// <seealso cref="FlaxEditor.Content.ContentProxy" />
[ContentContextMenu("New/Shader Header (.hlsl)")]
public class ShaderHeaderProxy : ShaderBaseProxy
{
/// <inheritdoc />
public override void Create(string outputPath, object arg)
{
File.WriteAllText(outputPath, "\n", Encoding.UTF8);
}
/// <inheritdoc />
public override Color AccentColor => Color.FromRGB(0x2545a5);
/// <inheritdoc />
public override string FileExtension => "hlsl";
/// <inheritdoc />
public override string Name => "Shader Header";
/// <inheritdoc />
public override bool IsProxyFor(ContentItem item)
{
return false;
}
}
}

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();
}

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

@@ -55,7 +55,7 @@ public class ModelPrefabEditor : GenericEditor
// Creates the import path UI
var group = layout.Group("Import Path");
Utilities.Utils.CreateImportPathUI(group, modelPrefab.ImportPath, false);
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

@@ -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

@@ -21,6 +21,7 @@ namespace FlaxEditor.CustomEditors.Editors
public sealed class LocalizedStringEditor : GenericEditor
{
private TextBoxElement _idElement, _valueElement;
private Button _viewStringButton;
/// <inheritdoc />
public override DisplayStyle Style => DisplayStyle.Inline;
@@ -70,6 +71,21 @@ namespace FlaxEditor.CustomEditors.Editors
};
addString.SetAnchorPreset(AnchorPresets.MiddleRight, false, true);
addString.ButtonClicked += OnAddStringClicked;
var viewString = new Button
{
Visible = false,
Width = 16.0f,
BackgroundColor = Color.White,
BackgroundColorHighlighted = Color.Gray,
BackgroundBrush = new SpriteBrush(Editor.Instance.Icons.Search12),
TooltipText = "Find localized text in Localized String Table asset for the current locale...",
Parent = valueElement.TextBox,
};
viewString.SetAnchorPreset(AnchorPresets.MiddleRight, false, true);
viewString.LocalX -= 16.0f;
viewString.ButtonClicked += OnViewStringClicked;
_viewStringButton = viewString;
}
/// <inheritdoc />
@@ -80,6 +96,7 @@ namespace FlaxEditor.CustomEditors.Editors
if (_valueElement != null)
{
_valueElement.TextBox.WatermarkText = Localization.GetString(_idElement.Text);
_viewStringButton.Visible = !string.IsNullOrEmpty(_valueElement.TextBox.WatermarkText);
}
}
@@ -92,14 +109,21 @@ namespace FlaxEditor.CustomEditors.Editors
_valueElement = null;
}
private void OnSelectStringClicked(Button button)
private bool GetSettings(out LocalizationSettings settings)
{
var settings = GameSettings.Load<LocalizationSettings>();
settings = GameSettings.Load<LocalizationSettings>();
if (settings?.LocalizedStringTables == null || settings.LocalizedStringTables.Length == 0)
{
MessageBox.Show("No valid localization settings setup.");
return;
return true;
}
return false;
}
private void OnSelectStringClicked(Button button)
{
if (GetSettings(out var settings))
return;
Profiler.BeginEvent("LocalizedStringEditor.OnSelectStringClicked");
var allKeys = new HashSet<string>();
for (int i = 0; i < settings.LocalizedStringTables.Length; i++)
@@ -136,6 +160,7 @@ namespace FlaxEditor.CustomEditors.Editors
{
menu.Hide();
_idElement.TextBox.SetTextAsUser(after[0].Text);
_valueElement.TextBox.SetTextAsUser(string.Empty);
}
};
searchBox.TextChanged += delegate
@@ -158,12 +183,8 @@ namespace FlaxEditor.CustomEditors.Editors
private void OnAddStringClicked(Button button)
{
var settings = GameSettings.Load<LocalizationSettings>();
if (settings?.LocalizedStringTables == null || settings.LocalizedStringTables.Length == 0)
{
MessageBox.Show("No valid localization settings setup.");
if (GetSettings(out var settings))
return;
}
Profiler.BeginEvent("LocalizedStringEditor.OnAddStringClicked");
var allKeys = new HashSet<string>();
for (int i = 0; i < settings.LocalizedStringTables.Length; i++)
@@ -231,5 +252,30 @@ namespace FlaxEditor.CustomEditors.Editors
_idElement.TextBox.SetTextAsUser(newKey);
Profiler.EndEvent();
}
private void OnViewStringClicked(Button button)
{
if (GetSettings(out var settings))
return;
var id = _idElement.TextBox.Text;
var value = _valueElement.TextBox.WatermarkText;
for (int i = 0; i < settings.LocalizedStringTables.Length; i++)
{
var table = settings.LocalizedStringTables[i];
if (table && !table.WaitForLoaded())
{
var entries = table.Entries;
if (entries.TryGetValue(id, out var messages))
{
if (messages.Length != 0 && messages[0] == value)
{
Editor.Instance.ContentEditing.Open(table);
return;
}
}
}
}
MessageBox.Show("Unable to find localized string table.");
}
}
}

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

@@ -35,7 +35,7 @@ namespace FlaxEditor.CustomEditors.Editors
}
_element = layout.TextBox(isMultiLine);
_defaultWatermarkColor = _element.TextBox.WatermarkTextColor;
_watermarkColor = _defaultWatermarkColor = _element.TextBox.WatermarkTextColor;
if (watermarkAttribute is WatermarkAttribute watermark)
{
_watermarkText = watermark.WatermarkText;

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

@@ -285,6 +285,17 @@ namespace FlaxEditor.GUI.ContextMenu
}
}
private static void ForceDefocus(ContainerControl c)
{
foreach (var cc in c.Children)
{
if (cc.ContainsFocus)
cc.Defocus();
if (cc is ContainerControl ccc)
ForceDefocus(ccc);
}
}
/// <summary>
/// Hide popup menu and all child menus.
/// </summary>
@@ -299,6 +310,9 @@ namespace FlaxEditor.GUI.ContextMenu
// Close child
HideChild();
// Force defocus
ForceDefocus(this);
// Unlink from window
Parent = null;

View File

@@ -41,7 +41,7 @@ namespace FlaxEditor.GUI.Input
get => _min;
set
{
if (!Mathd.NearEqual(_min, value))
if (_min != value)
{
if (value > _max)
throw new ArgumentException();
@@ -58,7 +58,7 @@ namespace FlaxEditor.GUI.Input
get => _max;
set
{
if (!Mathd.NearEqual(_max, value))
if (_max != value)
{
if (value < _min)
throw new ArgumentException();

View File

@@ -38,7 +38,7 @@ namespace FlaxEditor.GUI.Input
get => _min;
set
{
if (!Mathf.NearEqual(_min, value))
if (_min != value)
{
if (value > _max)
throw new ArgumentException();
@@ -54,7 +54,7 @@ namespace FlaxEditor.GUI.Input
get => _max;
set
{
if (!Mathf.NearEqual(_max, value))
if (_max != value)
{
if (value < _min)
throw new ArgumentException();

View File

@@ -54,7 +54,7 @@ namespace FlaxEditor.GUI.Input
set
{
value = Mathf.Clamp(value, Minimum, Maximum);
if (!Mathf.NearEqual(value, _value))
if (value != _value)
{
_value = value;
@@ -311,7 +311,7 @@ namespace FlaxEditor.GUI.Input
get => _min;
set
{
if (!Mathf.NearEqual(_min, value))
if (_min != value)
{
if (value > _max)
throw new ArgumentException();
@@ -330,7 +330,7 @@ namespace FlaxEditor.GUI.Input
get => _max;
set
{
if (!Mathf.NearEqual(_max, value))
if (_max != value)
{
if (value < _min)
throw new ArgumentException();

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

@@ -1135,6 +1135,7 @@ namespace FlaxEditor.Modules
Proxy.Add(new FontProxy());
Proxy.Add(new ShaderProxy());
Proxy.Add(new ShaderSourceProxy());
Proxy.Add(new ShaderHeaderProxy());
Proxy.Add(new ParticleEmitterProxy());
Proxy.Add(new ParticleEmitterFunctionProxy());
Proxy.Add(new ParticleSystemProxy());

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

@@ -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

@@ -628,19 +628,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

@@ -35,7 +35,8 @@ namespace FlaxEditor.SceneGraph
return false;
}
BoundingSphere sphere = new BoundingSphere(Transform.Translation, 7.0f);
var center = _actor.Transform.Translation;
ViewportIconsRenderer.GetBounds(ref center, ref ray.Ray.Position, out var sphere);
return CollisionsHelper.RayIntersectsSphere(ref ray.Ray, ref sphere, out distance);
}
}

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

@@ -534,7 +534,7 @@ namespace FlaxEditor.Surface.Archetypes
Title = "Tangent Vector",
Description = "World space tangent vector",
Flags = NodeFlags.MaterialGraph,
Size = new Float2(160, 40),
Size = new Float2(160, 30),
Elements = new[]
{
NodeElementArchetype.Factory.Output(0, "Tangent", typeof(Float3), 0),
@@ -546,7 +546,7 @@ namespace FlaxEditor.Surface.Archetypes
Title = "Bitangent Vector",
Description = "World space bitangent vector",
Flags = NodeFlags.MaterialGraph,
Size = new Float2(160, 40),
Size = new Float2(160, 30),
Elements = new[]
{
NodeElementArchetype.Factory.Output(0, "Bitangent", typeof(Float3), 0),
@@ -558,7 +558,7 @@ namespace FlaxEditor.Surface.Archetypes
Title = "Camera Position",
Description = "World space camera location",
Flags = NodeFlags.MaterialGraph,
Size = new Float2(160, 40),
Size = new Float2(160, 30),
Elements = new[]
{
NodeElementArchetype.Factory.Output(0, "XYZ", typeof(Float3), 0),
@@ -570,7 +570,7 @@ namespace FlaxEditor.Surface.Archetypes
Title = "Per Instance Random",
Description = "Per object instance random value (normalized to range 0-1)",
Flags = NodeFlags.MaterialGraph,
Size = new Float2(200, 40),
Size = new Float2(200, 30),
Elements = new[]
{
NodeElementArchetype.Factory.Output(0, "", typeof(float), 0),
@@ -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;
}
@@ -498,11 +488,9 @@ namespace FlaxEditor.Surface
// Check if user is pressing control
if (Root.GetKey(KeyboardKeys.Control))
{
// Add to selection
if (!controlUnderMouse.IsSelected)
{
AddToSelection(controlUnderMouse);
}
// Add/remove from selection
controlUnderMouse.IsSelected = !controlUnderMouse.IsSelected;
SelectionChanged?.Invoke();
}
// Check if node isn't selected
else if (!controlUnderMouse.IsSelected)

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

@@ -415,13 +415,10 @@ namespace FlaxEditor.Utilities
/// </summary>
/// <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(0);
var textBox = parentLayout.TextBox().TextBox;
textBox.TooltipText = "Source asset path. Can be relative or absolute to the project. Path is not editable here.";
textBox.IsReadOnly = true;
@@ -1503,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

@@ -24,8 +24,6 @@
#include "Engine/Level/Actors/SpotLight.h"
#include "Engine/Video/VideoPlayer.h"
#define ICON_RADIUS 7.0f
enum class IconTypes
{
PointLight,
@@ -67,6 +65,16 @@ public:
};
ViewportIconsRendererService ViewportIconsRendererServiceInstance;
float ViewportIconsRenderer::Scale = 1.0f;
void ViewportIconsRenderer::GetBounds(const Vector3& position, const Vector3& viewPosition, BoundingSphere& bounds)
{
constexpr Real minSize = 7.0;
constexpr Real maxSize = 30.0;
Real scale = Math::Square(Vector3::Distance(position, viewPosition) / 1000.0f);
Real radius = minSize + Math::Min<Real>(scale, 1.0f) * (maxSize - minSize);
bounds = BoundingSphere(position, radius * Scale);
}
void ViewportIconsRenderer::DrawIcons(RenderContext& renderContext, Actor* actor)
{
@@ -134,7 +142,8 @@ void ViewportIconsRendererService::DrawIcons(RenderContext& renderContext, Scene
AssetReference<Texture> texture;
for (Actor* icon : icons)
{
BoundingSphere sphere(icon->GetPosition() - renderContext.View.Origin, ICON_RADIUS);
BoundingSphere sphere;
ViewportIconsRenderer::GetBounds(icon->GetPosition() - renderContext.View.Origin, renderContext.View.Position, sphere);
if (!frustum.Intersects(sphere))
continue;
IconTypes iconType;
@@ -174,7 +183,7 @@ void ViewportIconsRendererService::DrawIcons(RenderContext& renderContext, Scene
if (draw.Buffer)
{
// Create world matrix
Matrix::Scaling(ICON_RADIUS * 2.0f, m2);
Matrix::Scaling((float)sphere.Radius * 2.0f, m2);
Matrix::RotationY(PI, world);
Matrix::Multiply(m2, world, m1);
Matrix::Billboard(sphere.Center, view.Position, Vector3::Up, view.Direction, m2);
@@ -194,14 +203,15 @@ void ViewportIconsRendererService::DrawIcons(RenderContext& renderContext, Actor
auto& view = renderContext.View;
const BoundingFrustum frustum = view.Frustum;
Matrix m1, m2, world;
BoundingSphere sphere(actor->GetPosition() - renderContext.View.Origin, ICON_RADIUS);
BoundingSphere sphere;
ViewportIconsRenderer::GetBounds(actor->GetPosition() - renderContext.View.Origin, renderContext.View.Position, sphere);
IconTypes iconType;
AssetReference<Texture> texture;
if (frustum.Intersects(sphere) && ActorTypeToIconType.TryGet(actor->GetTypeHandle(), iconType))
{
// Create world matrix
Matrix::Scaling(ICON_RADIUS * 2.0f, m2);
Matrix::Scaling((float)sphere.Radius * 2.0f, m2);
Matrix::RotationY(PI, world);
Matrix::Multiply(m2, world, m1);
Matrix::Billboard(sphere.Center, view.Position, Vector3::Up, view.Direction, m2);

View File

@@ -17,6 +17,19 @@ API_CLASS(Static, Namespace="FlaxEditor") class FLAXENGINE_API ViewportIconsRend
DECLARE_SCRIPTING_TYPE_NO_SPAWN(ViewportIconsRenderer);
public:
/// <summary>
/// Global scale of the icons.
/// </summary>
API_FIELD() static float Scale;
/// <summary>
/// Draws the icons for the actors in the given scene (or actor tree).
/// </summary>
/// <param name="position">The icon position.</param>
/// <param name="viewPosition">The viewer position.</param>
/// <param name="bounds">The computed bounds for the icon.</param>
API_FUNCTION() static void GetBounds(API_PARAM(Ref) const Vector3& position, API_PARAM(Ref) const Vector3& viewPosition, API_PARAM(Out) BoundingSphere& bounds);
/// <summary>
/// Draws the icons for the actors in the given scene (or actor tree).
/// </summary>

View File

@@ -910,7 +910,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;
}
@@ -959,7 +959,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;
}
@@ -1002,19 +1002,79 @@ namespace FlaxEditor.Viewport
ViewWidgetButtonMenu.VisibleChanged += control => resolutionValue.Value = ResolutionScale;
}
// Icons Scale
{
var icons = ViewWidgetButtonMenu.AddButton("Icons");
icons.CloseMenuOnClick = false;
var iconsValue = new FloatValueBox(ViewportIconsRenderer.Scale, xLocationForExtras, 2, 70.0f, 0.01f, 100.0f, 0.001f)
{
Parent = icons
};
iconsValue.ValueChanged += () => ViewportIconsRenderer.Scale = iconsValue.Value;
ViewWidgetButtonMenu.VisibleChanged += control => iconsValue.Value = ViewportIconsRenderer.Scale;
}
#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;
@@ -1933,8 +1993,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;
@@ -1952,13 +2021,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"),
@@ -1972,16 +2041,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)
@@ -2014,43 +2083,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

@@ -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

@@ -76,29 +76,29 @@ namespace FlaxEditor.Windows.Assets
// Transparency
[EditorOrder(200), DefaultValue(MaterialTransparentLightingMode.Surface), VisibleIf(nameof(IsStandard)), EditorDisplay("Transparency"), Tooltip("Transparent material lighting mode.")]
[EditorOrder(200), DefaultValue(MaterialTransparentLightingMode.Surface), VisibleIf(nameof(IsForward)), EditorDisplay("Transparency"), Tooltip("Transparent material lighting mode.")]
public MaterialTransparentLightingMode TransparentLightingMode;
[EditorOrder(205), DefaultValue(true), VisibleIf(nameof(IsStandard)), EditorDisplay("Transparency"), Tooltip("Enables reflections when rendering material.")]
[EditorOrder(205), DefaultValue(true), VisibleIf(nameof(IsForward)), EditorDisplay("Transparency"), Tooltip("Enables reflections when rendering material.")]
public bool EnableReflections;
[VisibleIf(nameof(EnableReflections))]
[EditorOrder(210), DefaultValue(false), VisibleIf(nameof(IsStandard)), EditorDisplay("Transparency"), Tooltip("Enables Screen Space Reflections when rendering material.")]
[EditorOrder(210), DefaultValue(false), VisibleIf(nameof(IsForward)), EditorDisplay("Transparency"), Tooltip("Enables Screen Space Reflections when rendering material.")]
public bool EnableScreenSpaceReflections;
[EditorOrder(210), DefaultValue(true), VisibleIf(nameof(IsStandard)), EditorDisplay("Transparency"), Tooltip("Enables fog effects when rendering material.")]
[EditorOrder(210), DefaultValue(true), VisibleIf(nameof(IsForward)), EditorDisplay("Transparency"), Tooltip("Enables fog effects when rendering material.")]
public bool EnableFog;
[EditorOrder(220), DefaultValue(true), VisibleIf(nameof(IsStandard)), EditorDisplay("Transparency"), Tooltip("Enables distortion effect when rendering.")]
[EditorOrder(220), DefaultValue(true), VisibleIf(nameof(IsForward)), EditorDisplay("Transparency"), Tooltip("Enables distortion effect when rendering.")]
public bool EnableDistortion;
[EditorOrder(224), DefaultValue(false), VisibleIf(nameof(IsStandard)), EditorDisplay("Transparency"), Tooltip("Enables sampling Global Illumination in material (eg. light probes or volumetric lightmap).")]
[EditorOrder(224), DefaultValue(false), VisibleIf(nameof(IsForward)), EditorDisplay("Transparency"), Tooltip("Enables sampling Global Illumination in material (eg. light probes or volumetric lightmap).")]
public bool EnableGlobalIllumination;
[EditorOrder(225), DefaultValue(false), VisibleIf(nameof(IsStandard)), EditorDisplay("Transparency"), Tooltip("Enables refraction offset based on the difference between the per-pixel normal and the per-vertex normal. Useful for large water-like surfaces.")]
[EditorOrder(225), DefaultValue(false), VisibleIf(nameof(IsForward)), EditorDisplay("Transparency"), Tooltip("Enables refraction offset based on the difference between the per-pixel normal and the per-vertex normal. Useful for large water-like surfaces.")]
public bool PixelNormalOffsetRefraction;
[EditorOrder(230), DefaultValue(0.12f), VisibleIf(nameof(IsStandard)), EditorDisplay("Transparency"), Tooltip("Controls opacity values clipping point."), Limit(0.0f, 1.0f, 0.01f)]
[EditorOrder(230), DefaultValue(0.12f), VisibleIf(nameof(IsForward)), EditorDisplay("Transparency"), Tooltip("Controls opacity values clipping point."), Limit(0.0f, 1.0f, 0.01f)]
public float OpacityThreshold;
// Tessellation
@@ -146,6 +146,7 @@ namespace FlaxEditor.Windows.Assets
private bool IsDecal => Domain == MaterialDomain.Decal;
private bool IsGUI => Domain == MaterialDomain.GUI;
private bool IsStandard => Domain == MaterialDomain.Surface || Domain == MaterialDomain.Terrain || Domain == MaterialDomain.Particle || Domain == MaterialDomain.Deformable;
private bool IsForward => Domain == MaterialDomain.Particle || ((Domain == MaterialDomain.Deformable || Domain == MaterialDomain.Surface) && BlendMode != MaterialBlendMode.Opaque);
private bool IsStandardOrGUI => IsStandard || IsGUI;
/// <summary>

View File

@@ -254,7 +254,8 @@ namespace FlaxEditor.Windows.Assets
if (lodIndex >= countLODs - loadedLODs)
{
var mesh = lod.GetMesh(0);
vertexLayout = mesh.VertexLayout;
if (mesh != null)
vertexLayout = mesh.VertexLayout;
if (vertexLayout != null && vertexLayout.Elements.Length != 0)
break;
vertexLayout = null;
@@ -759,7 +760,6 @@ namespace FlaxEditor.Windows.Assets
var importSettingsField = typeof(ImportPropertiesProxyBase).GetField(nameof(ImportSettings), BindingFlags.NonPublic | BindingFlags.Instance);
var importSettingsValues = new ValueContainer(new ScriptMemberInfo(importSettingsField)) { proxy.ImportSettings };
importSettingsGroup.Object(importSettingsValues);
importSettingsGroup.Space(3);
// Creates the import path UI
var group = layout.Group("Import Path");

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

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

@@ -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

@@ -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

@@ -48,6 +48,7 @@ namespace FlaxEditor.Windows
: base(editor, true, ScrollBars.None)
{
Title = "Scene";
Icon = editor.Icons.Globe32;
// Scene searching query input box
var headerPanel = new ContainerControl
@@ -84,6 +85,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);
}