Merge remote-tracking branch 'origin/master' into 1.9
# Conflicts: # Flax.flaxproj
This commit is contained in:
8
.github/workflows/build_mac.yml
vendored
8
.github/workflows/build_mac.yml
vendored
@@ -9,7 +9,7 @@ jobs:
|
||||
|
||||
# Editor
|
||||
editor-mac:
|
||||
name: Editor (Mac, Development x64)
|
||||
name: Editor (Mac, Development ARM64)
|
||||
runs-on: "macos-latest"
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
@@ -30,11 +30,11 @@ jobs:
|
||||
git lfs pull
|
||||
- name: Build
|
||||
run: |
|
||||
./Development/Scripts/Mac/CallBuildTool.sh -build -log -printSDKs -dotnet=8 -arch=x64 -platform=Mac -configuration=Development -buildtargets=FlaxEditor
|
||||
./Development/Scripts/Mac/CallBuildTool.sh -build -log -printSDKs -dotnet=8 -arch=ARM64 -platform=Mac -configuration=Development -buildtargets=FlaxEditor
|
||||
|
||||
# Game
|
||||
game-mac:
|
||||
name: Game (Mac, Release x64)
|
||||
name: Game (Mac, Release ARM64)
|
||||
runs-on: "macos-latest"
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
@@ -55,4 +55,4 @@ jobs:
|
||||
git lfs pull
|
||||
- name: Build
|
||||
run: |
|
||||
./Development/Scripts/Mac/CallBuildTool.sh -build -log -printSDKs -dotnet=8 -arch=x64 -platform=Mac -configuration=Release -buildtargets=FlaxGame
|
||||
./Development/Scripts/Mac/CallBuildTool.sh -build -log -printSDKs -dotnet=8 -arch=ARM64 -platform=Mac -configuration=Release -buildtargets=FlaxGame
|
||||
|
||||
4
.github/workflows/cd.yml
vendored
4
.github/workflows/cd.yml
vendored
@@ -166,7 +166,7 @@ jobs:
|
||||
dotnet workload --info
|
||||
- name: Build
|
||||
run: |
|
||||
./PackageEditor.command -arch=x64 -platform=Mac -deployOutput=Output
|
||||
./PackageEditor.command -arch=ARM64 -platform=Mac -deployOutput=Output
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
@@ -194,7 +194,7 @@ jobs:
|
||||
dotnet workload --info
|
||||
- name: Build
|
||||
run: |
|
||||
./PackagePlatforms.command -arch=x64 -platform=Mac -deployOutput=Output
|
||||
./PackagePlatforms.command -arch=ARM64 -platform=Mac -deployOutput=Output
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
|
||||
@@ -89,7 +89,7 @@ namespace FlaxEditor.Content
|
||||
// Cleanup it after usage
|
||||
Object.Destroy(actor, 20.0f);
|
||||
}
|
||||
else if (actor.Scene != null)
|
||||
else if (actor.HasScene)
|
||||
{
|
||||
// Create prefab with identity transform so the actor instance on a level will have it customized
|
||||
resetTransform = true;
|
||||
|
||||
@@ -203,16 +203,16 @@ bool AndroidPlatformTools::OnPostProcess(CookingData& data)
|
||||
switch (defaultOrienation)
|
||||
{
|
||||
case AndroidPlatformSettings::ScreenOrientation::Portrait:
|
||||
orientation = String("portrait");
|
||||
orientation = String("userPortrait");
|
||||
break;
|
||||
case AndroidPlatformSettings::ScreenOrientation::PortraitReverse:
|
||||
orientation = String("reversePortrait");
|
||||
case AndroidPlatformSettings::ScreenOrientation::Landscape:
|
||||
orientation = String("userLandscape");
|
||||
break;
|
||||
case AndroidPlatformSettings::ScreenOrientation::LandscapeRight:
|
||||
orientation = String("landscape");
|
||||
case AndroidPlatformSettings::ScreenOrientation::SensorPortrait:
|
||||
orientation = String("sensorPortrait");
|
||||
break;
|
||||
case AndroidPlatformSettings::ScreenOrientation::LandscapeLeft:
|
||||
orientation = String("reverseLandscape");
|
||||
case AndroidPlatformSettings::ScreenOrientation::SensorLandscape:
|
||||
orientation = String("sensorLandscape");
|
||||
break;
|
||||
case AndroidPlatformSettings::ScreenOrientation::AutoRotation:
|
||||
orientation = String("fullSensor");
|
||||
@@ -266,9 +266,33 @@ bool AndroidPlatformTools::OnPostProcess(CookingData& data)
|
||||
}
|
||||
}
|
||||
|
||||
String versionCode = platformSettings->VersionCode;
|
||||
if (versionCode.IsEmpty())
|
||||
{
|
||||
LOG(Error, "AndroidSettings: Invalid version code");
|
||||
return true;
|
||||
}
|
||||
|
||||
String minimumSdk = platformSettings->MinimumAPILevel;
|
||||
if (minimumSdk.IsEmpty())
|
||||
{
|
||||
LOG(Error, "AndroidSettings: Invalid minimum API level");
|
||||
return true;
|
||||
}
|
||||
|
||||
String targetSdk = platformSettings->TargetAPILevel;
|
||||
if (targetSdk.IsEmpty())
|
||||
{
|
||||
LOG(Error, "AndroidSettings: Invalid target API level");
|
||||
return true;
|
||||
}
|
||||
|
||||
// Format project template files
|
||||
const String buildGradlePath = data.OriginalOutputPath / TEXT("app/build.gradle");
|
||||
EditorUtilities::ReplaceInFile(buildGradlePath, TEXT("${PackageName}"), packageName);
|
||||
EditorUtilities::ReplaceInFile(buildGradlePath, TEXT("${VersionCode}"), versionCode);
|
||||
EditorUtilities::ReplaceInFile(buildGradlePath, TEXT("${MinimumSdk}"), minimumSdk);
|
||||
EditorUtilities::ReplaceInFile(buildGradlePath, TEXT("${TargetSdk}"), targetSdk);
|
||||
EditorUtilities::ReplaceInFile(buildGradlePath, TEXT("${ProjectVersion}"), projectVersion);
|
||||
EditorUtilities::ReplaceInFile(buildGradlePath, TEXT("${PackageAbi}"), abi);
|
||||
const String manifestPath = data.OriginalOutputPath / TEXT("app/src/main/AndroidManifest.xml");
|
||||
@@ -339,7 +363,7 @@ bool AndroidPlatformTools::OnPostProcess(CookingData& data)
|
||||
Platform::CreateProcess(procSettings);
|
||||
}
|
||||
#endif
|
||||
const bool distributionPackage = buildSettings->ForDistribution;
|
||||
const bool distributionPackage = buildSettings->ForDistribution || data.Configuration == BuildConfiguration::Release;
|
||||
{
|
||||
CreateProcessSettings procSettings;
|
||||
procSettings.FileName = String::Format(TEXT("\"{0}\" {1}"), data.OriginalOutputPath / gradlew, distributionPackage ? TEXT("assemble") : TEXT("assembleDebug"));
|
||||
|
||||
@@ -52,13 +52,18 @@ namespace FlaxEditor.CustomEditors
|
||||
// Check if use provided editor
|
||||
if (overrideEditor != null)
|
||||
return overrideEditor;
|
||||
ScriptType targetType = values.Type;
|
||||
|
||||
// Special case if property is a pure object type and all values are the same type
|
||||
if (values.Type.Type == typeof(object) && values.Count > 0 && values[0] != null && !values.HasDifferentTypes)
|
||||
if (targetType.Type == typeof(object) && values.Count > 0 && values[0] != null && !values.HasDifferentTypes)
|
||||
return CreateEditor(TypeUtils.GetObjectType(values[0]), canUseRefPicker);
|
||||
|
||||
// Special case if property is interface but the value is implemented as Scripting Object that should use reference picker
|
||||
if (targetType.IsInterface && canUseRefPicker && values.Count > 0 && values[0] is FlaxEngine.Object)
|
||||
return new DummyEditor();
|
||||
|
||||
// Use editor for the property type
|
||||
return CreateEditor(values.Type, canUseRefPicker);
|
||||
return CreateEditor(targetType, canUseRefPicker);
|
||||
}
|
||||
|
||||
internal static CustomEditor CreateEditor(ScriptType targetType, bool canUseRefPicker = true)
|
||||
|
||||
@@ -291,7 +291,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
if (editor.ChildrenEditors.Count == 0 || (isRefEdited && editor is CollectionEditor))
|
||||
result = CreateDiffNode(editor);
|
||||
bool isScriptEditorWithRefValue = editor is ScriptsEditor && editor.Values.HasReferenceValue;
|
||||
bool isActorEditorInLevel = editor is ActorEditor && editor.Values[0] is Actor actor && actor.IsPrefabRoot && actor.Scene != null;
|
||||
bool isActorEditorInLevel = editor is ActorEditor && editor.Values[0] is Actor actor && actor.IsPrefabRoot && actor.HasScene;
|
||||
for (int i = 0; i < editor.ChildrenEditors.Count; i++)
|
||||
{
|
||||
var childEditor = editor.ChildrenEditors[i];
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using FlaxEditor.Content.Settings;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
@@ -12,7 +13,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
[CustomEditor(typeof(LayersMask)), DefaultEditor]
|
||||
internal class LayersMaskEditor : CustomEditor
|
||||
{
|
||||
private CheckBox[] _checkBoxes;
|
||||
private List<CheckBox> _checkBoxes;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Initialize(LayoutElementsContainer layout)
|
||||
@@ -24,16 +25,18 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
return;
|
||||
}
|
||||
|
||||
_checkBoxes = new CheckBox[layers.Length];
|
||||
_checkBoxes = new List<CheckBox>();
|
||||
for (int i = 0; i < layers.Length; i++)
|
||||
{
|
||||
var layer = layers[i];
|
||||
var property = layout.AddPropertyItem(layer);
|
||||
if (string.IsNullOrEmpty(layer))
|
||||
continue;
|
||||
var property = layout.AddPropertyItem($"{i}: {layer}");
|
||||
var checkbox = property.Checkbox().CheckBox;
|
||||
UpdateCheckbox(checkbox, i);
|
||||
checkbox.Tag = i;
|
||||
checkbox.StateChanged += OnCheckboxStateChanged;
|
||||
_checkBoxes[i] = checkbox;
|
||||
_checkBoxes.Add(checkbox);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,9 +53,9 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
{
|
||||
if (_checkBoxes != null)
|
||||
{
|
||||
for (int i = 0; i < _checkBoxes.Length; i++)
|
||||
for (int i = 0; i < _checkBoxes.Count; i++)
|
||||
{
|
||||
UpdateCheckbox(_checkBoxes[i], i);
|
||||
UpdateCheckbox(_checkBoxes[i], (int)_checkBoxes[i].Tag);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -45,6 +45,12 @@ public class ModelPrefabEditor : GenericEditor
|
||||
break;
|
||||
_prefabId = prefabObject.PrefabID;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The model was removed earlier
|
||||
_prefabId = Guid.Empty;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var button = layout.Button("Reimport", "Reimports the source asset as prefab.");
|
||||
|
||||
@@ -456,14 +456,47 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
|
||||
for (int i = 0; i < layout.Children.Count; i++)
|
||||
{
|
||||
if (layout.Children[i] is GroupElement group && group.Panel.HeaderText == "Transform")
|
||||
if (layout.Children[i] is GroupElement group && group.Panel.HeaderText.Equals("Transform", StringComparison.Ordinal))
|
||||
{
|
||||
VerticalPanelElement mainHor = VerticalPanelWithoutMargin(group);
|
||||
CreateTransformElements(mainHor, ValuesTypes);
|
||||
group.ContainerControl.ChangeChildIndex(mainHor.Control, 0);
|
||||
layout.Children.Remove(group);
|
||||
layout.ContainerControl.Children.Remove(group.Panel);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Setup transform
|
||||
if (Presenter is LayoutElementsContainer l)
|
||||
{
|
||||
var transformGroup = l.Group("Transform");
|
||||
VerticalPanelElement mainHor = VerticalPanelWithoutMargin(transformGroup);
|
||||
CreateTransformElements(mainHor, ValuesTypes);
|
||||
|
||||
ScriptMemberInfo scaleInfo = ValuesTypes[0].GetProperty("Scale");
|
||||
ItemInfo scaleItem = new ItemInfo(scaleInfo);
|
||||
transformGroup.Property("Scale", scaleItem.GetValues(Values));
|
||||
|
||||
ScriptMemberInfo pivotInfo = ValuesTypes[0].GetProperty("Pivot");
|
||||
ItemInfo pivotItem = new ItemInfo(pivotInfo);
|
||||
transformGroup.Property("Pivot", pivotItem.GetValues(Values));
|
||||
|
||||
ScriptMemberInfo shearInfo = ValuesTypes[0].GetProperty("Shear");
|
||||
ItemInfo shearItem = new ItemInfo(shearInfo);
|
||||
transformGroup.Property("Shear", shearItem.GetValues(Values));
|
||||
|
||||
ScriptMemberInfo rotationInfo = ValuesTypes[0].GetProperty("Rotation");
|
||||
ItemInfo rotationItem = new ItemInfo(rotationInfo);
|
||||
transformGroup.Property("Rotation", rotationItem.GetValues(Values));
|
||||
|
||||
// Get position of general tab
|
||||
for (int i = 0; i < l.Children.Count; i++)
|
||||
{
|
||||
if (l.Children[i] is GroupElement g && g.Panel.HeaderText.Equals("General", StringComparison.Ordinal) && i + 1 <= l.Children.Count)
|
||||
{
|
||||
Presenter.ContainerControl.ChangeChildIndex(transformGroup.Control, i + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateTransformElements(LayoutElementsContainer main, ScriptType[] valueTypes)
|
||||
@@ -645,7 +678,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
{
|
||||
var grid = UniformGridTwoByOne(el);
|
||||
grid.CustomControl.SlotPadding = new Margin(5, 5, 1, 1);
|
||||
var label = grid.Label(text);
|
||||
var label = grid.Label(text, TextAlignment.Far);
|
||||
var editor = grid.Object(values);
|
||||
if (editor is FloatEditor floatEditor && floatEditor.Element is FloatValueElement floatEditorElement)
|
||||
{
|
||||
|
||||
17
Source/Editor/CustomEditors/Editors/DummyEditor.cs
Normal file
17
Source/Editor/CustomEditors/Editors/DummyEditor.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
||||
|
||||
namespace FlaxEditor.CustomEditors.Editors
|
||||
{
|
||||
internal sealed class DummyEditor : CustomEditor
|
||||
{
|
||||
public override void Initialize(LayoutElementsContainer layout)
|
||||
{
|
||||
string valueName;
|
||||
if (Values.Count != 0 && Values[0] != null)
|
||||
valueName = Values[0].ToString();
|
||||
else
|
||||
valueName = "null";
|
||||
layout.Label($"{valueName} ({Values.Type})");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,9 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
public sealed class StringEditor : CustomEditor
|
||||
{
|
||||
private TextBoxElement _element;
|
||||
private string _watermarkText;
|
||||
private Color _watermarkColor;
|
||||
private Color _defaultWatermarkColor;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override DisplayStyle Style => DisplayStyle.Inline;
|
||||
@@ -21,15 +24,26 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
public override void Initialize(LayoutElementsContainer layout)
|
||||
{
|
||||
bool isMultiLine = false;
|
||||
_watermarkText = string.Empty;
|
||||
|
||||
var attributes = Values.GetAttributes();
|
||||
var multiLine = attributes?.FirstOrDefault(x => x is MultilineTextAttribute);
|
||||
var watermarkAttribute = attributes?.FirstOrDefault(x => x is WatermarkAttribute);
|
||||
if (multiLine != null)
|
||||
{
|
||||
isMultiLine = true;
|
||||
}
|
||||
|
||||
_element = layout.TextBox(isMultiLine);
|
||||
_defaultWatermarkColor = _element.TextBox.WatermarkTextColor;
|
||||
if (watermarkAttribute is WatermarkAttribute watermark)
|
||||
{
|
||||
_watermarkText = watermark.WatermarkText;
|
||||
var watermarkColor = watermark.WatermarkColor > 0 ? Color.FromRGBA(watermark.WatermarkColor) : FlaxEngine.GUI.Style.Current.ForegroundDisabled;
|
||||
_watermarkColor = watermarkColor;
|
||||
_element.TextBox.WatermarkText = watermark.WatermarkText;
|
||||
_element.TextBox.WatermarkTextColor = watermarkColor;
|
||||
}
|
||||
_element.TextBox.EditEnd += () => SetValue(_element.Text);
|
||||
}
|
||||
|
||||
@@ -41,12 +55,14 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
if (HasDifferentValues)
|
||||
{
|
||||
_element.TextBox.Text = string.Empty;
|
||||
_element.TextBox.WatermarkTextColor = _defaultWatermarkColor;
|
||||
_element.TextBox.WatermarkText = "Different values";
|
||||
}
|
||||
else
|
||||
{
|
||||
_element.TextBox.Text = (string)Values[0];
|
||||
_element.TextBox.WatermarkText = string.Empty;
|
||||
_element.TextBox.WatermarkTextColor = _watermarkColor;
|
||||
_element.TextBox.WatermarkText = _watermarkText;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -242,7 +242,7 @@ namespace FlaxEditor.CustomEditors.GUI
|
||||
float namesWidth = _splitterValue * Width;
|
||||
int count = _element.Labels.Count;
|
||||
float[] yStarts = new float[count + 1];
|
||||
for (int i = 1; i < count; i++)
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var label = _element.Labels[i];
|
||||
|
||||
@@ -251,9 +251,13 @@ namespace FlaxEditor.CustomEditors.GUI
|
||||
else if (_children.Count <= label.FirstChildControlIndex)
|
||||
yStarts[i] = y;
|
||||
else
|
||||
{
|
||||
yStarts[i] = _children[label.FirstChildControlIndex].Top;
|
||||
if (i == count - 1)
|
||||
yStarts[i + 1] = _children[label.FirstChildControlIndex].Bottom;
|
||||
}
|
||||
|
||||
}
|
||||
yStarts[count] = y;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var label = _element.Labels[i];
|
||||
|
||||
@@ -264,6 +264,7 @@ namespace FlaxEditor.GUI.Dialogs
|
||||
{
|
||||
Text = "+",
|
||||
Parent = this,
|
||||
TooltipText = "Save Color.",
|
||||
Tag = null,
|
||||
};
|
||||
savedColorButton.ButtonClicked += (b) => OnSavedColorButtonClicked(b);
|
||||
@@ -498,6 +499,7 @@ namespace FlaxEditor.GUI.Dialogs
|
||||
{
|
||||
Text = "+",
|
||||
Parent = this,
|
||||
TooltipText = "Save Color.",
|
||||
Tag = null,
|
||||
};
|
||||
savedColorButton.ButtonClicked += (b) => OnSavedColorButtonClicked(b);
|
||||
|
||||
@@ -311,7 +311,9 @@ namespace FlaxEditor.GUI.Dialogs
|
||||
// Alpha
|
||||
float alphaY = _slider2Rect.Height * (1 - _color.A);
|
||||
var alphaR = new Rectangle(_slider2Rect.X - slidersOffset, _slider2Rect.Y + alphaY - slidersThickness / 2, _slider2Rect.Width + slidersOffset * 2, slidersThickness);
|
||||
Render2D.FillRectangle(_slider2Rect, _color, _color, Color.Transparent, Color.Transparent);
|
||||
var color = _color;
|
||||
color.A = 1; // Keep slider 2 fill rect from changing color alpha while selecting.
|
||||
Render2D.FillRectangle(_slider2Rect, color, color, Color.Transparent, Color.Transparent);
|
||||
Render2D.DrawRectangle(_slider2Rect, _isMouseDownSlider2 ? style.BackgroundSelected : Color.Black);
|
||||
Render2D.DrawRectangle(alphaR, _isMouseDownSlider2 ? Color.White : Color.Gray);
|
||||
}
|
||||
|
||||
107
Source/Editor/GUI/Drag/DragControlType.cs
Normal file
107
Source/Editor/GUI/Drag/DragControlType.cs
Normal file
@@ -0,0 +1,107 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using FlaxEditor.SceneGraph;
|
||||
using FlaxEditor.Scripting;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
using FlaxEngine.Utilities;
|
||||
|
||||
namespace FlaxEditor.GUI.Drag;
|
||||
|
||||
/// <summary>
|
||||
/// Control type drag handler.
|
||||
/// </summary>
|
||||
public sealed class DragControlType : DragActorType<DragEventArgs>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DragControlType"/> class.
|
||||
/// </summary>
|
||||
/// <param name="validateFunction">The validation function</param>
|
||||
public DragControlType(Func<ScriptType, bool> validateFunction)
|
||||
: base(validateFunction)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper class for handling control type drag and drop (for spawning).
|
||||
/// </summary>
|
||||
/// <seealso cref="Control" />
|
||||
/// <seealso cref="ActorNode" />
|
||||
public class DragControlType<U> : DragHelper<ScriptType, U> where U : DragEventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// The default prefix for drag data used for actor type drag and drop.
|
||||
/// </summary>
|
||||
public const string DragPrefix = "CTYPE!?";
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new DragHelper
|
||||
/// </summary>
|
||||
/// <param name="validateFunction">The validation function</param>
|
||||
public DragControlType(Func<ScriptType, bool> validateFunction)
|
||||
: base(validateFunction)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override DragData ToDragData(ScriptType item) => GetDragData(item);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override DragData ToDragData(IEnumerable<ScriptType> items)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the drag data.
|
||||
/// </summary>
|
||||
/// <param name="item">The control type.</param>
|
||||
/// <returns>The data</returns>
|
||||
public static DragData GetDragData(Type item)
|
||||
{
|
||||
if (item == null)
|
||||
throw new ArgumentNullException();
|
||||
return new DragDataText(DragPrefix + item.FullName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the drag data.
|
||||
/// </summary>
|
||||
/// <param name="item">The control type.</param>
|
||||
/// <returns>The data</returns>
|
||||
public static DragData GetDragData(ScriptType item)
|
||||
{
|
||||
if (item == ScriptType.Null)
|
||||
throw new ArgumentNullException();
|
||||
return new DragDataText(DragPrefix + item.TypeName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to parse the drag data to extract <see cref="Type"/> collection.
|
||||
/// </summary>
|
||||
/// <param name="data">The data.</param>
|
||||
/// <returns>Gathered objects or empty array if cannot get any valid.</returns>
|
||||
public override IEnumerable<ScriptType> FromDragData(DragData data)
|
||||
{
|
||||
if (data is DragDataText dataText)
|
||||
{
|
||||
if (dataText.Text.StartsWith(DragPrefix))
|
||||
{
|
||||
// Remove prefix and parse spitted names
|
||||
var types = dataText.Text.Remove(0, DragPrefix.Length).Split('\n');
|
||||
var results = new List<ScriptType>(types.Length);
|
||||
for (int i = 0; i < types.Length; i++)
|
||||
{
|
||||
// Find type
|
||||
var obj = TypeUtils.GetType(types[i]);
|
||||
if (obj)
|
||||
results.Add(obj);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
}
|
||||
return Utils.GetEmptyArray<ScriptType>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,6 @@ namespace FlaxEditor.GUI.Tree
|
||||
private bool _isMouseDown;
|
||||
private float _mouseDownTime;
|
||||
private Float2 _mouseDownPos;
|
||||
private Color _cachedTextColor;
|
||||
|
||||
private DragItemPositioning _dragOverMode;
|
||||
private bool _isDragOverHeader;
|
||||
@@ -91,6 +90,11 @@ namespace FlaxEditor.GUI.Tree
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the node is collapsed in the hierarchy (is collapsed or any of its parents is collapsed).
|
||||
/// </summary>
|
||||
public bool IsCollapsedInHierarchy => IsCollapsed || (Parent is TreeNode parentNode && parentNode.IsCollapsedInHierarchy);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the text margin.
|
||||
/// </summary>
|
||||
@@ -604,9 +608,6 @@ namespace FlaxEditor.GUI.Tree
|
||||
/// <inheritdoc />
|
||||
public override void Update(float deltaTime)
|
||||
{
|
||||
// Cache text color
|
||||
_cachedTextColor = CacheTextColor();
|
||||
|
||||
// Drop/down animation
|
||||
if (_animationProgress < 1.0f)
|
||||
{
|
||||
@@ -676,7 +677,8 @@ namespace FlaxEditor.GUI.Tree
|
||||
}
|
||||
|
||||
// Draw text
|
||||
Render2D.DrawText(TextFont.GetFont(), _text, textRect, _cachedTextColor, TextAlignment.Near, TextAlignment.Center);
|
||||
Color textColor = CacheTextColor();
|
||||
Render2D.DrawText(TextFont.GetFont(), _text, textRect, textColor, TextAlignment.Near, TextAlignment.Center);
|
||||
|
||||
// Draw drag and drop effect
|
||||
if (IsDragOver && _tree.DraggedOverNode == this)
|
||||
@@ -712,6 +714,72 @@ namespace FlaxEditor.GUI.Tree
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void DrawChildren()
|
||||
{
|
||||
// Draw all visible child controls
|
||||
var children = _children;
|
||||
if (children.Count == 0)
|
||||
return;
|
||||
|
||||
if (CullChildren)
|
||||
{
|
||||
Render2D.PeekClip(out var globalClipping);
|
||||
Render2D.PeekTransform(out var globalTransform);
|
||||
|
||||
// Try to estimate the rough location of the first node, assuming the node height is constant
|
||||
var firstChildGlobalRect = GetChildGlobalRectangle(children[0], ref globalTransform);
|
||||
var firstVisibleChild = Math.Clamp((int)Math.Floor((globalClipping.Y - firstChildGlobalRect.Top) / firstChildGlobalRect.Height) + 1, 0, children.Count - 1);
|
||||
if (GetChildGlobalRectangle(children[firstVisibleChild], ref globalTransform).Top > globalClipping.Top || !children[firstVisibleChild].Visible)
|
||||
{
|
||||
// Estimate overshoot, either it's partially visible or hidden in the tree
|
||||
for (; firstVisibleChild > 0; firstVisibleChild--)
|
||||
{
|
||||
var child = children[firstVisibleChild];
|
||||
if (!child.Visible)
|
||||
continue;
|
||||
|
||||
if (GetChildGlobalRectangle(child, ref globalTransform).Top < globalClipping.Top)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = firstVisibleChild; i < children.Count; i++)
|
||||
{
|
||||
var child = children[i];
|
||||
if (!child.Visible)
|
||||
continue;
|
||||
|
||||
var childGlobalRect = GetChildGlobalRectangle(child, ref globalTransform);
|
||||
if (!globalClipping.Intersects(ref childGlobalRect))
|
||||
break;
|
||||
|
||||
Render2D.PushTransform(ref child._cachedTransform);
|
||||
child.Draw();
|
||||
Render2D.PopTransform();
|
||||
}
|
||||
|
||||
static Rectangle GetChildGlobalRectangle(Control control, ref Matrix3x3 globalTransform)
|
||||
{
|
||||
Matrix3x3.Multiply(ref control._cachedTransform, ref globalTransform, out var globalChildTransform);
|
||||
return new Rectangle(globalChildTransform.M31, globalChildTransform.M32, control.Width * globalChildTransform.M11, control.Height * globalChildTransform.M22);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < children.Count; i++)
|
||||
{
|
||||
var child = children[i];
|
||||
if (child.Visible)
|
||||
{
|
||||
Render2D.PushTransform(ref child._cachedTransform);
|
||||
child.Draw();
|
||||
Render2D.PopTransform();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool OnMouseDown(Float2 location, MouseButton button)
|
||||
{
|
||||
@@ -996,7 +1064,7 @@ namespace FlaxEditor.GUI.Tree
|
||||
// Expand node if mouse goes over arrow
|
||||
if (ArrowRect.Contains(location) && HasAnyVisibleChild)
|
||||
Expand(true);
|
||||
|
||||
|
||||
if (!_isDragOverHeader)
|
||||
result = OnDragEnterHeader(data);
|
||||
else
|
||||
@@ -1104,7 +1172,6 @@ namespace FlaxEditor.GUI.Tree
|
||||
{
|
||||
// TODO: perform layout for any non-TreeNode controls
|
||||
_cachedHeight = _headerHeight;
|
||||
_cachedTextColor = CacheTextColor();
|
||||
Size = new Float2(width, _headerHeight);
|
||||
}
|
||||
|
||||
@@ -1154,7 +1221,6 @@ namespace FlaxEditor.GUI.Tree
|
||||
}
|
||||
|
||||
_cachedHeight = height;
|
||||
_cachedTextColor = CacheTextColor();
|
||||
Height = Mathf.Max(_headerHeight, y);
|
||||
}
|
||||
|
||||
|
||||
@@ -227,7 +227,7 @@ namespace FlaxEditor.Modules
|
||||
|
||||
// When applying changes to prefab from actor in level ignore it's root transformation (see ActorEditor.ProcessDiff)
|
||||
var originalTransform = instance.LocalTransform;
|
||||
if (instance.IsPrefabRoot && instance.Scene != null)
|
||||
if (instance.IsPrefabRoot && instance.HasScene)
|
||||
instance.LocalTransform = prefab.GetDefaultInstance().Transform;
|
||||
|
||||
// Call backend
|
||||
|
||||
@@ -640,7 +640,7 @@ namespace FlaxEditor.Modules
|
||||
cm.AddButton("Visual Script Debugger", Editor.Windows.VisualScriptDebuggerWin.FocusOrShow);
|
||||
cm.AddSeparator();
|
||||
cm.AddButton("Save window layout", Editor.Windows.SaveLayout);
|
||||
_menuWindowApplyWindowLayout = cm.AddChildMenu("Apply window layout");
|
||||
_menuWindowApplyWindowLayout = cm.AddChildMenu("Window layouts");
|
||||
cm.AddButton("Restore default layout", Editor.Windows.LoadDefaultLayout);
|
||||
|
||||
// Help
|
||||
|
||||
@@ -255,6 +255,17 @@ namespace FlaxEditor.Options
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure custom fonts are valid, reset if not
|
||||
var defaultInterfaceOptions = new InterfaceOptions();
|
||||
if (Style.Current.FontTitle == null)
|
||||
Style.Current.FontTitle = defaultInterfaceOptions.TitleFont.GetFont();
|
||||
if (Style.Current.FontSmall == null)
|
||||
Style.Current.FontSmall = defaultInterfaceOptions.SmallFont.GetFont();
|
||||
if (Style.Current.FontMedium == null)
|
||||
Style.Current.FontMedium = defaultInterfaceOptions.MediumFont.GetFont();
|
||||
if (Style.Current.FontLarge == null)
|
||||
Style.Current.FontLarge = defaultInterfaceOptions.LargeFont.GetFont();
|
||||
|
||||
// Set fallback fonts
|
||||
var fallbackFonts = Options.Interface.FallbackFonts;
|
||||
if (fallbackFonts == null || fallbackFonts.Length == 0 || fallbackFonts.All(x => x == null))
|
||||
|
||||
@@ -29,6 +29,7 @@ namespace FlaxEditor.SceneGraph.GUI
|
||||
private DragScripts _dragScripts;
|
||||
private DragAssets _dragAssets;
|
||||
private DragActorType _dragActorType;
|
||||
private DragControlType _dragControlType;
|
||||
private DragScriptItems _dragScriptItems;
|
||||
private DragHandlers _dragHandlers;
|
||||
private List<Rectangle> _highlights;
|
||||
@@ -68,7 +69,7 @@ namespace FlaxEditor.SceneGraph.GUI
|
||||
Visible = (actor.HideFlags & HideFlags.HideInHierarchy) == 0;
|
||||
|
||||
// Pick the correct id when inside a prefab window.
|
||||
var id = actor.HasPrefabLink && actor.Scene == null ? actor.PrefabObjectID : actor.ID;
|
||||
var id = actor.HasPrefabLink && !actor.HasScene ? actor.PrefabObjectID : actor.ID;
|
||||
if (Editor.Instance.ProjectCache.IsExpandedActor(ref id))
|
||||
{
|
||||
Expand(true);
|
||||
@@ -97,7 +98,7 @@ namespace FlaxEditor.SceneGraph.GUI
|
||||
parentTreeNode.IsLayoutLocked = false;
|
||||
|
||||
// Skip UI update if node won't be in a view
|
||||
if (parentTreeNode.IsCollapsed)
|
||||
if (parentTreeNode.IsCollapsedInHierarchy)
|
||||
{
|
||||
UnlockChildrenRecursive();
|
||||
}
|
||||
@@ -291,7 +292,7 @@ namespace FlaxEditor.SceneGraph.GUI
|
||||
return Style.Current.ForegroundGrey;
|
||||
}
|
||||
|
||||
if (actor.Scene != null && Editor.Instance.StateMachine.IsPlayMode && actor.IsStatic)
|
||||
if (actor.HasScene && Editor.Instance.StateMachine.IsPlayMode && actor.IsStatic)
|
||||
{
|
||||
// Static
|
||||
return color * 0.85f;
|
||||
@@ -354,7 +355,7 @@ namespace FlaxEditor.SceneGraph.GUI
|
||||
private void OnRenamed(RenamePopup renamePopup)
|
||||
{
|
||||
using (new UndoBlock(ActorNode.Root.Undo, Actor, "Rename"))
|
||||
Actor.Name = renamePopup.Text;
|
||||
Actor.Name = renamePopup.Text.Trim();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -366,7 +367,7 @@ namespace FlaxEditor.SceneGraph.GUI
|
||||
if (!IsLayoutLocked && actor)
|
||||
{
|
||||
// Pick the correct id when inside a prefab window.
|
||||
var id = actor.HasPrefabLink && actor.Scene == null ? actor.PrefabObjectID : actor.ID;
|
||||
var id = actor.HasPrefabLink && !actor.HasScene ? actor.PrefabObjectID : actor.ID;
|
||||
Editor.Instance.ProjectCache.SetExpandedActor(ref id, IsExpanded);
|
||||
}
|
||||
}
|
||||
@@ -439,6 +440,17 @@ namespace FlaxEditor.SceneGraph.GUI
|
||||
}
|
||||
if (_dragActorType.OnDragEnter(data))
|
||||
return _dragActorType.Effect;
|
||||
|
||||
// Check if drag control type
|
||||
if (_dragControlType == null)
|
||||
{
|
||||
_dragControlType = new DragControlType(ValidateDragControlType);
|
||||
_dragHandlers.Add(_dragControlType);
|
||||
}
|
||||
if (_dragControlType.OnDragEnter(data))
|
||||
return _dragControlType.Effect;
|
||||
|
||||
// Check if drag script item
|
||||
if (_dragScriptItems == null)
|
||||
{
|
||||
_dragScriptItems = new DragScriptItems(ValidateDragScriptItem);
|
||||
@@ -572,10 +584,33 @@ namespace FlaxEditor.SceneGraph.GUI
|
||||
Editor.LogWarning("Failed to spawn actor of type " + item.TypeName);
|
||||
continue;
|
||||
}
|
||||
actor.StaticFlags = Actor.StaticFlags;
|
||||
actor.StaticFlags = newParent.StaticFlags;
|
||||
actor.Name = item.Name;
|
||||
actor.Transform = Actor.Transform;
|
||||
ActorNode.Root.Spawn(actor, Actor);
|
||||
ActorNode.Root.Spawn(actor, newParent);
|
||||
actor.OrderInParent = newOrder;
|
||||
}
|
||||
result = DragDropEffect.Move;
|
||||
}
|
||||
// Drag control type
|
||||
else if (_dragControlType != null && _dragControlType.HasValidDrag)
|
||||
{
|
||||
for (int i = 0; i < _dragControlType.Objects.Count; i++)
|
||||
{
|
||||
var item = _dragControlType.Objects[i];
|
||||
var control = item.CreateInstance() as Control;
|
||||
if (control == null)
|
||||
{
|
||||
Editor.LogWarning("Failed to spawn UIControl with control type " + item.TypeName);
|
||||
continue;
|
||||
}
|
||||
var uiControl = new UIControl
|
||||
{
|
||||
Control = control,
|
||||
StaticFlags = newParent.StaticFlags,
|
||||
Name = item.Name,
|
||||
};
|
||||
ActorNode.Root.Spawn(uiControl, newParent);
|
||||
uiControl.OrderInParent = newOrder;
|
||||
}
|
||||
result = DragDropEffect.Move;
|
||||
}
|
||||
@@ -640,8 +675,8 @@ namespace FlaxEditor.SceneGraph.GUI
|
||||
private bool ValidateDragScript(Script script)
|
||||
{
|
||||
// Reject dragging scripts not linked to scene (eg. from prefab) or in the opposite way
|
||||
var thisHasScene = Actor.Scene != null;
|
||||
var otherHasScene = script.Scene != null;
|
||||
var thisHasScene = Actor.HasScene;
|
||||
var otherHasScene = script.HasScene;
|
||||
if (thisHasScene != otherHasScene)
|
||||
return false;
|
||||
|
||||
@@ -656,7 +691,12 @@ namespace FlaxEditor.SceneGraph.GUI
|
||||
|
||||
private static bool ValidateDragActorType(ScriptType actorType)
|
||||
{
|
||||
return true;
|
||||
return Editor.Instance.CodeEditing.Actors.Get().Contains(actorType);
|
||||
}
|
||||
|
||||
private static bool ValidateDragControlType(ScriptType controlType)
|
||||
{
|
||||
return Editor.Instance.CodeEditing.Controls.Get().Contains(controlType);
|
||||
}
|
||||
|
||||
private static bool ValidateDragScriptItem(ScriptItem script)
|
||||
@@ -704,6 +744,7 @@ namespace FlaxEditor.SceneGraph.GUI
|
||||
_dragScripts = null;
|
||||
_dragAssets = null;
|
||||
_dragActorType = null;
|
||||
_dragControlType = null;
|
||||
_dragScriptItems = null;
|
||||
_dragHandlers?.Clear();
|
||||
_dragHandlers = null;
|
||||
|
||||
@@ -91,7 +91,7 @@ namespace FlaxEditor.SceneGraph
|
||||
private void OnActorSpawned(Actor actor)
|
||||
{
|
||||
// Skip actors from game
|
||||
if (actor.Scene != null)
|
||||
if (actor.HasScene)
|
||||
return;
|
||||
|
||||
// Check if it has parent
|
||||
|
||||
@@ -186,6 +186,18 @@ namespace FlaxEditor.Surface.Archetypes
|
||||
|
||||
base.OnEndMouseCapture();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool OnKeyDown(KeyboardKeys key)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case KeyboardKeys.Delete:
|
||||
_editor.SetAsset(_index, Guid.Empty);
|
||||
return true;
|
||||
}
|
||||
return base.OnKeyDown(key);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -430,7 +430,7 @@ namespace FlaxEditor.Surface.Archetypes
|
||||
Title = "Smoothstep",
|
||||
Description = "Returns a smooth Hermite interpolation between 0 and 1, if value is in the range [min, max].",
|
||||
Flags = NodeFlags.MaterialGraph,
|
||||
Size = new Float2(120, 60),
|
||||
Size = new Float2(200, 60),
|
||||
ConnectionsHints = ConnectionsHint.Numeric,
|
||||
IndependentBoxes = new[] { 0, 1, 2 },
|
||||
DependentBoxes = new[] { 3 },
|
||||
|
||||
@@ -66,6 +66,8 @@ namespace FlaxEditor.Surface.Undo
|
||||
// Initialize
|
||||
if (node.Values != null && node.Values.Length == _nodeValues.Length)
|
||||
Array.Copy(_nodeValues, node.Values, _nodeValues.Length);
|
||||
else if (_nodeValues != null && (node.Archetype.Flags & NodeFlags.VariableValuesSize) != 0)
|
||||
node.Values = (object[])_nodeValues.Clone();
|
||||
else if (_nodeValues != null && _nodeValues.Length != 0)
|
||||
throw new InvalidOperationException("Invalid node values.");
|
||||
node.Location = _nodeLocation;
|
||||
|
||||
@@ -302,8 +302,17 @@ namespace FlaxEditor.Windows.Assets
|
||||
// TODO: improve the UI
|
||||
layout.Space(40);
|
||||
var addParamType = layout.ComboBox().ComboBox;
|
||||
addParamType.Items = AllowedTypes.Select(CustomEditorsUtil.GetTypeNameUI).ToList();
|
||||
addParamType.SelectedIndex = 0;
|
||||
object lastValue = null;
|
||||
foreach (var e in _proxy.DefaultValues)
|
||||
lastValue = e.Value;
|
||||
|
||||
var allowedTypes = AllowedTypes.Select(CustomEditorsUtil.GetTypeNameUI).ToList();
|
||||
int index = 0;
|
||||
if (lastValue != null)
|
||||
index = allowedTypes.FindIndex(x => x.Equals(CustomEditorsUtil.GetTypeNameUI(lastValue.GetType()), StringComparison.Ordinal));
|
||||
|
||||
addParamType.Items = allowedTypes;
|
||||
addParamType.SelectedIndex = index;
|
||||
_addParamType = addParamType;
|
||||
var addParamButton = layout.Button("Add").Button;
|
||||
addParamButton.Clicked += OnAddParamButtonClicked;
|
||||
|
||||
@@ -65,6 +65,7 @@ namespace FlaxEditor.Windows.Assets
|
||||
private PrefabWindow _window;
|
||||
private DragAssets _dragAssets;
|
||||
private DragActorType _dragActorType;
|
||||
private DragControlType _dragControlType;
|
||||
private DragScriptItems _dragScriptItems;
|
||||
private DragHandlers _dragHandlers;
|
||||
|
||||
@@ -83,7 +84,12 @@ namespace FlaxEditor.Windows.Assets
|
||||
|
||||
private static bool ValidateDragActorType(ScriptType actorType)
|
||||
{
|
||||
return true;
|
||||
return Editor.Instance.CodeEditing.Actors.Get().Contains(actorType);
|
||||
}
|
||||
|
||||
private static bool ValidateDragControlType(ScriptType controlType)
|
||||
{
|
||||
return Editor.Instance.CodeEditing.Controls.Get().Contains(controlType);
|
||||
}
|
||||
|
||||
private static bool ValidateDragScriptItem(ScriptItem script)
|
||||
@@ -113,6 +119,13 @@ namespace FlaxEditor.Windows.Assets
|
||||
}
|
||||
if (_dragActorType.OnDragEnter(data))
|
||||
return _dragActorType.Effect;
|
||||
if (_dragControlType == null)
|
||||
{
|
||||
_dragControlType = new DragControlType(ValidateDragControlType);
|
||||
_dragHandlers.Add(_dragControlType);
|
||||
}
|
||||
if (_dragControlType.OnDragEnter(data))
|
||||
return _dragControlType.Effect;
|
||||
if (_dragScriptItems == null)
|
||||
{
|
||||
_dragScriptItems = new DragScriptItems(ValidateDragScriptItem);
|
||||
@@ -176,6 +189,27 @@ namespace FlaxEditor.Windows.Assets
|
||||
}
|
||||
result = DragDropEffect.Move;
|
||||
}
|
||||
// Drag control type
|
||||
else if (_dragControlType != null && _dragControlType.HasValidDrag)
|
||||
{
|
||||
for (int i = 0; i < _dragControlType.Objects.Count; i++)
|
||||
{
|
||||
var item = _dragControlType.Objects[i];
|
||||
var control = item.CreateInstance() as Control;
|
||||
if (control == null)
|
||||
{
|
||||
Editor.LogWarning("Failed to spawn UIControl with control type " + item.TypeName);
|
||||
continue;
|
||||
}
|
||||
var uiControl = new UIControl
|
||||
{
|
||||
Control = control,
|
||||
Name = item.Name,
|
||||
};
|
||||
_window.Spawn(uiControl);
|
||||
}
|
||||
result = DragDropEffect.Move;
|
||||
}
|
||||
// Drag script item
|
||||
else if (_dragScriptItems != null && _dragScriptItems.HasValidDrag)
|
||||
{
|
||||
@@ -207,6 +241,7 @@ namespace FlaxEditor.Windows.Assets
|
||||
_window = null;
|
||||
_dragAssets = null;
|
||||
_dragActorType = null;
|
||||
_dragControlType = null;
|
||||
_dragScriptItems = null;
|
||||
_dragHandlers?.Clear();
|
||||
_dragHandlers = null;
|
||||
@@ -450,6 +485,7 @@ namespace FlaxEditor.Windows.Assets
|
||||
// Create undo action
|
||||
var action = new CustomDeleteActorsAction(new List<SceneGraphNode>(1) { actorNode }, true);
|
||||
Undo.AddAction(action);
|
||||
Focus();
|
||||
Select(actorNode);
|
||||
}
|
||||
|
||||
|
||||
@@ -542,6 +542,8 @@ namespace FlaxEditor.Windows
|
||||
return;
|
||||
}
|
||||
|
||||
newShortName = newShortName.Trim();
|
||||
|
||||
// Cache data
|
||||
string extension = item.IsFolder ? "" : Path.GetExtension(item.Path);
|
||||
var newPath = StringUtils.CombinePaths(item.ParentFolder.Path, newShortName + extension);
|
||||
|
||||
@@ -470,6 +470,10 @@ namespace FlaxEditor.Windows
|
||||
IsMaximized = false;
|
||||
IsBorderless = false;
|
||||
Cursor = CursorType.Default;
|
||||
Screen.CursorLock = CursorLockMode.None;
|
||||
if (Screen.MainWindow.IsMouseTracking)
|
||||
Screen.MainWindow.EndTrackingMouse();
|
||||
RootControl.GameRoot.EndMouseCapture();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -478,7 +482,7 @@ namespace FlaxEditor.Windows
|
||||
base.OnMouseLeave();
|
||||
|
||||
// Remove focus from game window when mouse moves out and the cursor is hidden during game
|
||||
if ((IsFocused || ContainsFocus) && Parent != null && Editor.IsPlayMode && !Screen.CursorVisible)
|
||||
if (ContainsFocus && Parent != null && Editor.IsPlayMode && !Screen.CursorVisible && Screen.CursorLock == CursorLockMode.None)
|
||||
{
|
||||
Parent.Focus();
|
||||
}
|
||||
|
||||
@@ -281,7 +281,7 @@ namespace FlaxEditor.Windows
|
||||
if (IsLayoutLocked)
|
||||
return;
|
||||
|
||||
_hScroll.Maximum = _output.TextSize.X;
|
||||
_hScroll.Maximum = Mathf.Max(_output.TextSize.X, _hScroll.Minimum);
|
||||
_vScroll.Maximum = Mathf.Max(_output.TextSize.Y - _output.Height, _vScroll.Minimum);
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ namespace FlaxEditor.Windows
|
||||
|
||||
private DragAssets _dragAssets;
|
||||
private DragActorType _dragActorType;
|
||||
private DragControlType _dragControlType;
|
||||
private DragScriptItems _dragScriptItems;
|
||||
private DragHandlers _dragHandlers;
|
||||
|
||||
@@ -275,7 +276,12 @@ namespace FlaxEditor.Windows
|
||||
|
||||
private static bool ValidateDragActorType(ScriptType actorType)
|
||||
{
|
||||
return true;
|
||||
return Editor.Instance.CodeEditing.Actors.Get().Contains(actorType);
|
||||
}
|
||||
|
||||
private static bool ValidateDragControlType(ScriptType controlType)
|
||||
{
|
||||
return Editor.Instance.CodeEditing.Controls.Get().Contains(controlType);
|
||||
}
|
||||
|
||||
private static bool ValidateDragScriptItem(ScriptItem script)
|
||||
@@ -390,6 +396,13 @@ namespace FlaxEditor.Windows
|
||||
}
|
||||
if (_dragActorType.OnDragEnter(data) && result == DragDropEffect.None)
|
||||
return _dragActorType.Effect;
|
||||
if (_dragControlType == null)
|
||||
{
|
||||
_dragControlType = new DragControlType(ValidateDragControlType);
|
||||
_dragHandlers.Add(_dragControlType);
|
||||
}
|
||||
if (_dragControlType.OnDragEnter(data) && result == DragDropEffect.None)
|
||||
return _dragControlType.Effect;
|
||||
if (_dragScriptItems == null)
|
||||
{
|
||||
_dragScriptItems = new DragScriptItems(ValidateDragScriptItem);
|
||||
@@ -462,6 +475,28 @@ namespace FlaxEditor.Windows
|
||||
}
|
||||
result = DragDropEffect.Move;
|
||||
}
|
||||
// Drag control type
|
||||
else if (_dragControlType != null && _dragControlType.HasValidDrag)
|
||||
{
|
||||
for (int i = 0; i < _dragControlType.Objects.Count; i++)
|
||||
{
|
||||
var item = _dragControlType.Objects[i];
|
||||
var control = item.CreateInstance() as Control;
|
||||
if (control == null)
|
||||
{
|
||||
Editor.LogWarning("Failed to spawn UIControl with control type " + item.TypeName);
|
||||
continue;
|
||||
}
|
||||
var uiControl = new UIControl
|
||||
{
|
||||
Control = control,
|
||||
Name = item.Name,
|
||||
};
|
||||
Level.SpawnActor(uiControl);
|
||||
Editor.Scene.MarkSceneEdited(uiControl.Scene);
|
||||
}
|
||||
result = DragDropEffect.Move;
|
||||
}
|
||||
// Drag script item
|
||||
else if (_dragScriptItems != null && _dragScriptItems.HasValidDrag)
|
||||
{
|
||||
@@ -495,6 +530,7 @@ namespace FlaxEditor.Windows
|
||||
{
|
||||
_dragAssets = null;
|
||||
_dragActorType = null;
|
||||
_dragControlType = null;
|
||||
_dragScriptItems = null;
|
||||
_dragHandlers?.Clear();
|
||||
_dragHandlers = null;
|
||||
|
||||
@@ -191,6 +191,52 @@ namespace FlaxEditor.Windows
|
||||
CreateGroupWithList(_actorGroups, "GUI");
|
||||
CreateGroupWithList(_actorGroups, "Other");
|
||||
|
||||
// Add control types to tabs
|
||||
foreach (var controlType in Editor.Instance.CodeEditing.Controls.Get())
|
||||
{
|
||||
if (controlType.IsAbstract)
|
||||
continue;
|
||||
_groupSearch.AddChild(CreateControlItem(Utilities.Utils.GetPropertyNameUI(controlType.Name), controlType));
|
||||
ActorToolboxAttribute attribute = null;
|
||||
foreach (var e in controlType.GetAttributes(false))
|
||||
{
|
||||
if (e is ActorToolboxAttribute actorToolboxAttribute)
|
||||
{
|
||||
attribute = actorToolboxAttribute;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (attribute == null)
|
||||
continue;
|
||||
var groupName = attribute.Group.Trim();
|
||||
|
||||
// Check if tab already exists and add it to the tab
|
||||
var actorTabExists = false;
|
||||
foreach (var child in _actorGroups.Children)
|
||||
{
|
||||
if (child is Tab tab)
|
||||
{
|
||||
if (string.Equals(tab.Text, groupName, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var tree = tab.GetChild<Panel>().GetChild<Tree>();
|
||||
if (tree != null)
|
||||
{
|
||||
tree.AddChild(string.IsNullOrEmpty(attribute.Name) ? CreateControlItem(Utilities.Utils.GetPropertyNameUI(controlType.Name), controlType) : CreateControlItem(attribute.Name, controlType));
|
||||
tree.SortChildren();
|
||||
}
|
||||
actorTabExists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (actorTabExists)
|
||||
continue;
|
||||
|
||||
var group = CreateGroupWithList(_actorGroups, groupName);
|
||||
group.AddChild(string.IsNullOrEmpty(attribute.Name) ? CreateControlItem(Utilities.Utils.GetPropertyNameUI(controlType.Name), controlType) : CreateControlItem(attribute.Name, controlType));
|
||||
group.SortChildren();
|
||||
}
|
||||
|
||||
// Add other actor types to respective tab based on attribute
|
||||
foreach (var actorType in Editor.CodeEditing.Actors.Get())
|
||||
{
|
||||
@@ -304,6 +350,11 @@ namespace FlaxEditor.Windows
|
||||
return new ScriptTypeItem(name, type, GUI.Drag.DragActorType.GetDragData(type));
|
||||
}
|
||||
|
||||
private Item CreateControlItem(string name, ScriptType type)
|
||||
{
|
||||
return new ScriptTypeItem(name, type, GUI.Drag.DragControlType.GetDragData(type));
|
||||
}
|
||||
|
||||
private ContainerControl CreateGroupWithList(Tabs parentTabs, string title, float topOffset = 0)
|
||||
{
|
||||
var tab = parentTabs.AddTab(new Tab(title));
|
||||
@@ -316,6 +367,7 @@ namespace FlaxEditor.Windows
|
||||
var tree = new Tree(false)
|
||||
{
|
||||
AnchorPreset = AnchorPresets.HorizontalStretchTop,
|
||||
Margin = new Margin(0, 0, 0, panel.ScrollBarsSize),
|
||||
IsScrollable = true,
|
||||
Parent = panel
|
||||
};
|
||||
|
||||
@@ -42,7 +42,7 @@ public:
|
||||
int32 ContentKey = 0;
|
||||
|
||||
/// <summary>
|
||||
/// If checked, the builds produced by the Game Cooker will be treated as for final game distribution (eg. for game store upload). Builds done this way cannot be tested on console devkits (eg. Xbox One, Xbox Scarlett).
|
||||
/// If checked, the builds produced by the Game Cooker will be treated as for final game distribution (eg. for game store upload). Builds done this way cannot be tested on console devkits (eg. Xbox One, Xbox Scarlett). Enabled by default for `Release` builds.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(40), EditorDisplay(\"General\")")
|
||||
bool ForDistribution = false;
|
||||
|
||||
@@ -286,14 +286,14 @@ void Engine::OnLateFixedUpdate()
|
||||
{
|
||||
PROFILE_CPU_NAMED("Late Fixed Update");
|
||||
|
||||
// Collect physics simulation results (does nothing if Simulate hasn't been called in the previous loop step)
|
||||
Physics::CollectResults();
|
||||
|
||||
// Call event
|
||||
LateFixedUpdate();
|
||||
|
||||
// Update services
|
||||
EngineService::OnLateFixedUpdate();
|
||||
|
||||
// Collect physics simulation results (does nothing if Simulate hasn't been called in the previous loop step)
|
||||
Physics::CollectResults();
|
||||
}
|
||||
|
||||
void Engine::OnUpdate()
|
||||
|
||||
@@ -586,8 +586,17 @@ namespace FlaxEngine.Interop
|
||||
internal static ManagedHandle GetArrayTypeFromElementType(ManagedHandle elementTypeHandle)
|
||||
{
|
||||
Type elementType = Unsafe.As<TypeHolder>(elementTypeHandle.Target);
|
||||
Type classType = ArrayFactory.GetArrayType(elementType);
|
||||
return GetTypeManagedHandle(classType);
|
||||
Type arrayType = ArrayFactory.GetArrayType(elementType);
|
||||
return GetTypeManagedHandle(arrayType);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
internal static ManagedHandle GetArrayTypeFromWrappedArray(ManagedHandle arrayHandle)
|
||||
{
|
||||
ManagedArray managedArray = Unsafe.As<ManagedArray>(arrayHandle.Target);
|
||||
Type elementType = managedArray.ArrayType.GetElementType();
|
||||
Type arrayType = ArrayFactory.GetArrayType(elementType);
|
||||
return GetTypeManagedHandle(arrayType);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
|
||||
@@ -33,6 +33,14 @@
|
||||
#define VULKAN_USE_DEBUG_LAYER GPU_ENABLE_DIAGNOSTICS
|
||||
#define VULKAN_USE_DEBUG_DATA (GPU_ENABLE_DIAGNOSTICS && COMPILE_WITH_DEV_ENV)
|
||||
|
||||
#ifndef VULKAN_USE_VALIDATION_CACHE
|
||||
#ifdef VK_EXT_validation_cache
|
||||
#define VULKAN_USE_VALIDATION_CACHE VK_EXT_validation_cache
|
||||
#else
|
||||
#define VULKAN_USE_VALIDATION_CACHE 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef VULKAN_USE_QUERIES
|
||||
#define VULKAN_USE_QUERIES 1
|
||||
#endif
|
||||
|
||||
@@ -39,7 +39,7 @@ static const char* GInstanceExtensions[] =
|
||||
VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME,
|
||||
VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
|
||||
#endif
|
||||
#if VK_EXT_validation_cache
|
||||
#if VULKAN_USE_VALIDATION_CACHE
|
||||
VK_EXT_VALIDATION_CACHE_EXTENSION_NAME,
|
||||
#endif
|
||||
#if defined(VK_KHR_display) && 0
|
||||
@@ -57,7 +57,7 @@ static const char* GDeviceExtensions[] =
|
||||
#if VK_KHR_maintenance1
|
||||
VK_KHR_MAINTENANCE1_EXTENSION_NAME,
|
||||
#endif
|
||||
#if VK_EXT_validation_cache
|
||||
#if VULKAN_USE_VALIDATION_CACHE
|
||||
VK_EXT_VALIDATION_CACHE_EXTENSION_NAME,
|
||||
#endif
|
||||
#if VK_KHR_sampler_mirror_clamp_to_edge
|
||||
@@ -582,7 +582,7 @@ void GPUDeviceVulkan::ParseOptionalDeviceExtensions(const Array<const char*>& de
|
||||
OptionalDeviceExtensions.HasKHRMaintenance2 = RenderToolsVulkan::HasExtension(deviceExtensions, VK_KHR_MAINTENANCE2_EXTENSION_NAME);
|
||||
#endif
|
||||
OptionalDeviceExtensions.HasMirrorClampToEdge = RenderToolsVulkan::HasExtension(deviceExtensions, VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME);
|
||||
#if VK_EXT_validation_cache
|
||||
#if VULKAN_USE_VALIDATION_CACHE
|
||||
OptionalDeviceExtensions.HasEXTValidationCache = RenderToolsVulkan::HasExtension(deviceExtensions, VK_EXT_VALIDATION_CACHE_EXTENSION_NAME);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1439,7 +1439,7 @@ bool GPUDeviceVulkan::SavePipelineCache()
|
||||
return File::WriteAllBytes(path, data);
|
||||
}
|
||||
|
||||
#if VK_EXT_validation_cache
|
||||
#if VULKAN_USE_VALIDATION_CACHE
|
||||
|
||||
void GetValidationCachePath(String& path)
|
||||
{
|
||||
@@ -1900,7 +1900,7 @@ bool GPUDeviceVulkan::Init()
|
||||
const VkResult result = vkCreatePipelineCache(Device, &pipelineCacheCreateInfo, nullptr, &PipelineCache);
|
||||
LOG_VULKAN_RESULT(result);
|
||||
}
|
||||
#if VK_EXT_validation_cache
|
||||
#if VULKAN_USE_VALIDATION_CACHE
|
||||
if (OptionalDeviceExtensions.HasEXTValidationCache && vkCreateValidationCacheEXT && vkDestroyValidationCacheEXT)
|
||||
{
|
||||
Array<uint8> data;
|
||||
@@ -1915,16 +1915,16 @@ bool GPUDeviceVulkan::Init()
|
||||
int32* dataPtr = (int32*)data.Get();
|
||||
if (*dataPtr > 0)
|
||||
{
|
||||
dataPtr++;
|
||||
const int32 version = *dataPtr++;
|
||||
const int32 versionExpected = VK_PIPELINE_CACHE_HEADER_VERSION_ONE;
|
||||
if (version == versionExpected)
|
||||
const int32 cacheSize = *dataPtr++;
|
||||
const int32 cacheVersion = *dataPtr++;
|
||||
const int32 cacheVersionExpected = VK_PIPELINE_CACHE_HEADER_VERSION_ONE;
|
||||
if (cacheVersion == cacheVersionExpected)
|
||||
{
|
||||
dataPtr += VK_UUID_SIZE / sizeof(int32);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(Warning, "Bad validation cache file, version: {0}, expected: {1}", version, versionExpected);
|
||||
LOG(Warning, "Bad validation cache file, version: {0}, expected: {1}", cacheVersion, cacheVersionExpected);
|
||||
data.Clear();
|
||||
}
|
||||
}
|
||||
@@ -2003,7 +2003,7 @@ void GPUDeviceVulkan::Dispose()
|
||||
vkDestroyPipelineCache(Device, PipelineCache, nullptr);
|
||||
PipelineCache = VK_NULL_HANDLE;
|
||||
}
|
||||
#if VK_EXT_validation_cache
|
||||
#if VULKAN_USE_VALIDATION_CACHE
|
||||
if (ValidationCache != VK_NULL_HANDLE)
|
||||
{
|
||||
if (SaveValidationCache())
|
||||
|
||||
@@ -400,7 +400,9 @@ public:
|
||||
uint32 HasKHRMaintenance1 : 1;
|
||||
uint32 HasKHRMaintenance2 : 1;
|
||||
uint32 HasMirrorClampToEdge : 1;
|
||||
#if VULKAN_USE_VALIDATION_CACHE
|
||||
uint32 HasEXTValidationCache : 1;
|
||||
#endif
|
||||
};
|
||||
|
||||
static void GetInstanceLayersAndExtensions(Array<const char*>& outInstanceExtensions, Array<const char*>& outInstanceLayers, bool& outDebugUtils);
|
||||
@@ -496,13 +498,11 @@ public:
|
||||
/// </summary>
|
||||
VkPipelineCache PipelineCache = VK_NULL_HANDLE;
|
||||
|
||||
#if VK_EXT_validation_cache
|
||||
|
||||
#if VULKAN_USE_VALIDATION_CACHE
|
||||
/// <summary>
|
||||
/// The optional validation cache.
|
||||
/// </summary>
|
||||
VkValidationCacheEXT ValidationCache = VK_NULL_HANDLE;
|
||||
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
@@ -584,12 +584,10 @@ public:
|
||||
bool SavePipelineCache();
|
||||
|
||||
#if VK_EXT_validation_cache
|
||||
|
||||
/// <summary>
|
||||
/// Saves the validation cache.
|
||||
/// </summary>
|
||||
bool SaveValidationCache();
|
||||
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
@@ -116,7 +116,7 @@ GPUShaderProgram* GPUShaderVulkan::CreateGPUShaderProgram(ShaderStage type, cons
|
||||
RenderToolsVulkan::ZeroStruct(createInfo, VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO);
|
||||
createInfo.codeSize = (size_t)spirv.Length();
|
||||
createInfo.pCode = (const uint32_t*)spirv.Get();
|
||||
#if VK_EXT_validation_cache
|
||||
#if VULKAN_USE_VALIDATION_CACHE
|
||||
VkShaderModuleValidationCacheCreateInfoEXT validationInfo;
|
||||
if (_device->ValidationCache != VK_NULL_HANDLE)
|
||||
{
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <vulkan/vulkan.h>
|
||||
#undef VK_EXT_debug_utils
|
||||
#undef VK_EXT_validation_cache
|
||||
#define VULKAN_USE_VALIDATION_CACHE 0
|
||||
#pragma clang diagnostic ignored "-Wpointer-bool-conversion"
|
||||
#pragma clang diagnostic ignored "-Wtautological-pointer-compare"
|
||||
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
// Support more backbuffers in case driver decides to use more (https://gitlab.freedesktop.org/apinheiro/mesa/-/issues/9)
|
||||
#define VULKAN_BACK_BUFFERS_COUNT_MAX 8
|
||||
|
||||
// Prevent wierd error 'Invalid VkValidationCacheEXT Object'
|
||||
#define VULKAN_USE_VALIDATION_CACHE 0
|
||||
|
||||
/// <summary>
|
||||
/// The implementation for the Vulkan API support for Linux platform.
|
||||
/// </summary>
|
||||
|
||||
@@ -382,6 +382,15 @@ public:
|
||||
return _isActiveInHierarchy != 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets value indicating if actor is in a scene.
|
||||
/// </summary>
|
||||
API_PROPERTY(Attributes="HideInEditor, NoSerialize")
|
||||
FORCE_INLINE bool HasScene() const
|
||||
{
|
||||
return _scene != nullptr;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if object is fully static on the scene, otherwise false.
|
||||
/// </summary>
|
||||
|
||||
@@ -8,9 +8,7 @@
|
||||
#include "Engine/Level/Prefabs/PrefabManager.h"
|
||||
#include "Engine/Level/Actor.h"
|
||||
#include "Engine/Threading/Threading.h"
|
||||
#if USE_EDITOR
|
||||
#include "Engine/Scripting/Scripting.h"
|
||||
#endif
|
||||
|
||||
REGISTER_JSON_ASSET(Prefab, "FlaxEngine.Prefab", true);
|
||||
|
||||
@@ -163,10 +161,10 @@ Asset::LoadResult Prefab::loadAsset()
|
||||
}
|
||||
}
|
||||
|
||||
#if USE_EDITOR
|
||||
// Register for scripts reload and unload (need to cleanup all user objects including scripts that may be attached to the default instance - it can be always restored)
|
||||
Scripting::ScriptsReloading.Bind<Prefab, &Prefab::DeleteDefaultInstance>(this);
|
||||
Scripting::ScriptsUnload.Bind<Prefab, &Prefab::DeleteDefaultInstance>(this);
|
||||
#if USE_EDITOR
|
||||
Scripting::ScriptsReloading.Bind<Prefab, &Prefab::DeleteDefaultInstance>(this);
|
||||
#endif
|
||||
|
||||
return LoadResult::Ok;
|
||||
@@ -174,10 +172,10 @@ Asset::LoadResult Prefab::loadAsset()
|
||||
|
||||
void Prefab::unload(bool isReloading)
|
||||
{
|
||||
#if USE_EDITOR
|
||||
// Unlink
|
||||
Scripting::ScriptsReloading.Unbind<Prefab, &Prefab::DeleteDefaultInstance>(this);
|
||||
Scripting::ScriptsUnload.Unbind<Prefab, &Prefab::DeleteDefaultInstance>(this);
|
||||
#if USE_EDITOR
|
||||
Scripting::ScriptsReloading.Unbind<Prefab, &Prefab::DeleteDefaultInstance>(this);
|
||||
#endif
|
||||
|
||||
// Base
|
||||
|
||||
@@ -55,6 +55,11 @@ Tag Tags::Get(const StringView& tagName)
|
||||
return tag;
|
||||
}
|
||||
|
||||
Tag Tags::Find(const StringView& tagName)
|
||||
{
|
||||
return Tag(List.Find(tagName) + 1);
|
||||
}
|
||||
|
||||
Array<Tag> Tags::GetSubTags(Tag parentTag)
|
||||
{
|
||||
Array<Tag> subTags;
|
||||
|
||||
@@ -92,6 +92,13 @@ API_CLASS(Static) class FLAXENGINE_API Tags
|
||||
/// <returns>The tag.</returns>
|
||||
API_FUNCTION() static Tag Get(const StringView& tagName);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the tag. Returns empty one if it doesn't exist.
|
||||
/// </summary>
|
||||
/// <param name="tagName">The tag name.</param>
|
||||
/// <returns>The tag (might be empty).</returns>
|
||||
API_FUNCTION() static Tag Find(const StringView& tagName);
|
||||
|
||||
/// <summary>
|
||||
/// Get all subtags of the specific Tag
|
||||
/// </summary>
|
||||
|
||||
@@ -23,24 +23,24 @@ API_CLASS(sealed, Namespace="FlaxEditor.Content.Settings") class FLAXENGINE_API
|
||||
API_ENUM() enum class FLAXENGINE_API ScreenOrientation
|
||||
{
|
||||
/// <summary>
|
||||
/// "portrait" mode
|
||||
/// "userPortrait" mode
|
||||
/// </summary>
|
||||
Portrait,
|
||||
|
||||
/// <summary>
|
||||
/// "reversePortrait" mode
|
||||
/// "userLandscape" mode
|
||||
/// </summary>
|
||||
PortraitReverse,
|
||||
Landscape,
|
||||
|
||||
/// <summary>
|
||||
/// "landscape" mode
|
||||
/// "sensorPortrait" mode
|
||||
/// </summary>
|
||||
LandscapeRight,
|
||||
SensorPortrait,
|
||||
|
||||
/// <summary>
|
||||
/// "reverseLandscape" mode
|
||||
/// "sensorLandscape" mode
|
||||
/// </summary>
|
||||
LandscapeLeft,
|
||||
SensorLandscape,
|
||||
|
||||
/// <summary>
|
||||
/// "fullSensor" mode
|
||||
@@ -72,6 +72,24 @@ API_CLASS(sealed, Namespace="FlaxEditor.Content.Settings") class FLAXENGINE_API
|
||||
API_FIELD(Attributes="EditorOrder(0), EditorDisplay(\"General\")")
|
||||
String PackageName = TEXT("com.${COMPANY_NAME}.${PROJECT_NAME}");
|
||||
|
||||
/// <summary>
|
||||
/// The application version code (eg. 1, 12, 123).
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(10), EditorDisplay(\"General\")")
|
||||
String VersionCode = TEXT("1");
|
||||
|
||||
/// <summary>
|
||||
/// The minimum Android API level (eg. 20, 28, 34).
|
||||
/// </summary>
|
||||
API_FIELD(Attributes = "EditorOrder(20), EditorDisplay(\"General\")")
|
||||
String MinimumAPILevel = TEXT("23");
|
||||
|
||||
/// <summary>
|
||||
/// The target Android API level (eg. 20, 28, 34).
|
||||
/// </summary>
|
||||
API_FIELD(Attributes = "EditorOrder(30), EditorDisplay(\"General\")")
|
||||
String TargetAPILevel = TEXT("33");
|
||||
|
||||
/// <summary>
|
||||
/// The application permissions list (eg. android.media.action.IMAGE_CAPTURE). Added to the generated manifest file.
|
||||
/// </summary>
|
||||
|
||||
@@ -770,14 +770,24 @@ void WindowsWindow::CheckForWindowResize()
|
||||
}
|
||||
}
|
||||
|
||||
void WindowsWindow::UpdateCursor() const
|
||||
void WindowsWindow::UpdateCursor()
|
||||
{
|
||||
// Don't hide cursor when window is not focused
|
||||
if (_cursor == CursorType::Hidden && _focused)
|
||||
{
|
||||
if (!_lastCursorHidden)
|
||||
{
|
||||
_lastCursorHidden = true;
|
||||
::ShowCursor(FALSE);
|
||||
}
|
||||
::SetCursor(nullptr);
|
||||
return;
|
||||
}
|
||||
else if (_lastCursorHidden)
|
||||
{
|
||||
_lastCursorHidden = false;
|
||||
::ShowCursor(TRUE);
|
||||
}
|
||||
|
||||
int32 index = 0;
|
||||
switch (_cursor)
|
||||
|
||||
@@ -28,6 +28,7 @@ private:
|
||||
bool _isSwitchingFullScreen = false;
|
||||
bool _trackingMouse = false;
|
||||
bool _clipCursorSet = false;
|
||||
bool _lastCursorHidden = false;
|
||||
bool _isDuringMaximize = false;
|
||||
Windows::HANDLE _monitor = nullptr;
|
||||
Windows::LONG _clipCursorRect[4];
|
||||
@@ -90,7 +91,7 @@ public:
|
||||
private:
|
||||
|
||||
void CheckForWindowResize();
|
||||
void UpdateCursor() const;
|
||||
void UpdateCursor();
|
||||
void UpdateRegion();
|
||||
|
||||
public:
|
||||
|
||||
@@ -1175,7 +1175,7 @@ void Render2D::DrawText(Font* font, const StringView& text, const Color& color,
|
||||
drawCall.AsChar.Mat = nullptr;
|
||||
}
|
||||
Float2 pointer = location;
|
||||
for (int32 currentIndex = 0; currentIndex <= text.Length(); currentIndex++)
|
||||
for (int32 currentIndex = 0; currentIndex < text.Length(); currentIndex++)
|
||||
{
|
||||
// Cache current character
|
||||
const Char currentChar = text[currentIndex];
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
|
||||
namespace FlaxEngine;
|
||||
|
||||
/// <summary>
|
||||
/// Used to add a watermark to a string textbox in the editor field
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
|
||||
public class WatermarkAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// The watermark text.
|
||||
/// </summary>
|
||||
public string WatermarkText;
|
||||
|
||||
/// <summary>
|
||||
/// The watermark color.
|
||||
/// </summary>
|
||||
public uint WatermarkColor;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="WatermarkAttribute"/> class.
|
||||
/// </summary>
|
||||
/// <param name="text">The watermark text.</param>
|
||||
public WatermarkAttribute(string text)
|
||||
{
|
||||
WatermarkText = text;
|
||||
WatermarkColor = 0; // default color of watermark in textbox
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="WatermarkAttribute"/> class.
|
||||
/// </summary>
|
||||
/// <param name="text">The watermark text.</param>
|
||||
/// <param name="color">The watermark color. 0 to use default.</param>
|
||||
public WatermarkAttribute(string text, uint color)
|
||||
{
|
||||
WatermarkText = text;
|
||||
WatermarkColor = color;
|
||||
}
|
||||
}
|
||||
@@ -40,6 +40,8 @@ void StdTypesContainer::Clear()
|
||||
Json_SerializeDiff = nullptr;
|
||||
Json_Deserialize = nullptr;
|
||||
|
||||
ManagedArrayClass = nullptr;
|
||||
|
||||
#if USE_EDITOR
|
||||
ExecuteInEditModeAttribute = nullptr;
|
||||
#endif
|
||||
@@ -88,6 +90,8 @@ bool StdTypesContainer::Gather()
|
||||
GET_METHOD(Json_SerializeDiff, JSON, "SerializeDiff", 3);
|
||||
GET_METHOD(Json_Deserialize, JSON, "Deserialize", 3);
|
||||
|
||||
GET_CLASS(FlaxEngine, ManagedArrayClass, "FlaxEngine.Interop.ManagedArray");
|
||||
|
||||
#if USE_EDITOR
|
||||
GET_CLASS(FlaxEngine, ExecuteInEditModeAttribute, "FlaxEngine.ExecuteInEditModeAttribute");
|
||||
#endif
|
||||
|
||||
@@ -45,6 +45,8 @@ public:
|
||||
MMethod* Json_SerializeDiff;
|
||||
MMethod* Json_Deserialize;
|
||||
|
||||
MClass* ManagedArrayClass;
|
||||
|
||||
#if USE_EDITOR
|
||||
MClass* ExecuteInEditModeAttribute;
|
||||
#endif
|
||||
|
||||
@@ -83,6 +83,7 @@ public:
|
||||
{
|
||||
static MArray* New(const MClass* elementKlass, int32 length);
|
||||
static MClass* GetClass(MClass* elementKlass);
|
||||
static MClass* GetArrayClass(const MArray* obj);
|
||||
static int32 GetLength(const MArray* obj);
|
||||
static void* GetAddress(const MArray* obj);
|
||||
static MArray* Unbox(MObject* obj);
|
||||
|
||||
@@ -394,14 +394,15 @@ Variant MUtils::UnboxVariant(MObject* value)
|
||||
case MTypes::Array:
|
||||
{
|
||||
void* ptr = MCore::Array::GetAddress((MArray*)value);
|
||||
MClass* elementClass = klass->GetElementClass();
|
||||
const MClass* arrayClass = klass == stdTypes.ManagedArrayClass ? MCore::Array::GetArrayClass((MArray*)value) : klass;
|
||||
const MClass* elementClass = arrayClass->GetElementClass();
|
||||
if (elementClass == MCore::TypeCache::Byte)
|
||||
{
|
||||
Variant v;
|
||||
v.SetBlob(ptr, MCore::Array::GetLength((MArray*)value));
|
||||
return v;
|
||||
}
|
||||
const StringAnsiView fullname = klass->GetFullName();
|
||||
const StringAnsiView fullname = arrayClass->GetFullName();
|
||||
Variant v;
|
||||
v.SetType(MoveTemp(VariantType(VariantType::Array, fullname)));
|
||||
auto& array = v.AsArray();
|
||||
|
||||
@@ -402,8 +402,15 @@ MArray* MCore::Array::New(const MClass* elementKlass, int32 length)
|
||||
|
||||
MClass* MCore::Array::GetClass(MClass* elementKlass)
|
||||
{
|
||||
static void* GetArrayLengthPtr = GetStaticMethodPointer(TEXT("GetArrayTypeFromElementType"));
|
||||
MType* typeHandle = (MType*)CallStaticMethod<void*, void*>(GetArrayLengthPtr, elementKlass->_handle);
|
||||
static void* GetArrayTypeFromElementTypePtr = GetStaticMethodPointer(TEXT("GetArrayTypeFromElementType"));
|
||||
MType* typeHandle = (MType*)CallStaticMethod<void*, void*>(GetArrayTypeFromElementTypePtr, elementKlass->_handle);
|
||||
return GetOrCreateClass(typeHandle);
|
||||
}
|
||||
|
||||
MClass* MCore::Array::GetArrayClass(const MArray* obj)
|
||||
{
|
||||
static void* GetArrayTypeFromWrappedArrayPtr = GetStaticMethodPointer(TEXT("GetArrayTypeFromWrappedArray"));
|
||||
MType* typeHandle = (MType*)CallStaticMethod<void*, void*>(GetArrayTypeFromWrappedArrayPtr, (void*)obj);
|
||||
return GetOrCreateClass(typeHandle);
|
||||
}
|
||||
|
||||
|
||||
@@ -795,6 +795,12 @@ MClass* MCore::Array::GetClass(MClass* elementKlass)
|
||||
return FindClass(monoClass);
|
||||
}
|
||||
|
||||
MClass* MCore::Array::GetArrayClass(const MArray* obj)
|
||||
{
|
||||
CRASH; // Not applicable
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int32 MCore::Array::GetLength(const MArray* obj)
|
||||
{
|
||||
return (int32)mono_array_length((MonoArray*)obj);
|
||||
|
||||
@@ -130,6 +130,11 @@ MClass* MCore::Array::GetClass(MClass* elementKlass)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MClass* MCore::Array::GetArrayClass(const MArray* obj)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int32 MCore::Array::GetLength(const MArray* obj)
|
||||
{
|
||||
return 0;
|
||||
|
||||
@@ -17,6 +17,12 @@ namespace FlaxEngine
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets value indicating if the actor owning the script is in a scene.
|
||||
/// </summary>
|
||||
[HideInEditor, NoSerialize]
|
||||
public bool HasScene => Actor?.HasScene ?? false;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the world space transformation of the actors owning this script.
|
||||
/// </summary>
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "Engine/Graphics/RenderView.h"
|
||||
#include "Engine/Graphics/RenderTask.h"
|
||||
#include "Engine/Graphics/Textures/GPUTexture.h"
|
||||
#include "Engine/Physics/PhysicsScene.h"
|
||||
#include "Engine/Profiler/ProfilerCPU.h"
|
||||
#include "Engine/Renderer/GlobalSignDistanceFieldPass.h"
|
||||
#include "Engine/Renderer/GI/GlobalSurfaceAtlasPass.h"
|
||||
@@ -807,6 +808,15 @@ void Terrain::OnEnable()
|
||||
#if TERRAIN_USE_PHYSICS_DEBUG
|
||||
GetSceneRendering()->AddPhysicsDebug<Terrain, &Terrain::DrawPhysicsDebug>(this);
|
||||
#endif
|
||||
void* scene = GetPhysicsScene()->GetPhysicsScene();
|
||||
for (int32 i = 0; i < _patches.Count(); i++)
|
||||
{
|
||||
auto patch = _patches[i];
|
||||
if (patch->_physicsActor)
|
||||
{
|
||||
PhysicsBackend::AddSceneActor(scene, patch->_physicsActor);
|
||||
}
|
||||
}
|
||||
|
||||
// Base
|
||||
Actor::OnEnable();
|
||||
|
||||
@@ -2126,7 +2126,8 @@ void TerrainPatch::CreateCollision()
|
||||
void* scene = _terrain->GetPhysicsScene()->GetPhysicsScene();
|
||||
_physicsActor = PhysicsBackend::CreateRigidStaticActor(nullptr, terrainTransform.LocalToWorld(_offset), terrainTransform.Orientation, scene);
|
||||
PhysicsBackend::AttachShape(_physicsShape, _physicsActor);
|
||||
PhysicsBackend::AddSceneActor(scene, _physicsActor);
|
||||
if (_terrain->IsDuringPlay())
|
||||
PhysicsBackend::AddSceneActor(scene, _physicsActor);
|
||||
}
|
||||
|
||||
bool TerrainPatch::CreateHeightField()
|
||||
|
||||
@@ -7,6 +7,7 @@ namespace FlaxEngine.GUI
|
||||
/// <summary>
|
||||
/// UI canvas scaling component for user interface that targets multiple different game resolutions (eg. mobile screens).
|
||||
/// </summary>
|
||||
[ActorToolbox("GUI")]
|
||||
public class CanvasScaler : ContainerControl
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace FlaxEngine.GUI
|
||||
/// <summary>
|
||||
/// Border control that draws the border around the control edges (inner and outer sides).
|
||||
/// </summary>
|
||||
[ActorToolbox("GUI")]
|
||||
public class Border : ContainerControl
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -7,6 +7,7 @@ namespace FlaxEngine.GUI
|
||||
/// <summary>
|
||||
/// Button control
|
||||
/// </summary>
|
||||
[ActorToolbox("GUI")]
|
||||
public class Button : ContainerControl
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -29,6 +29,7 @@ namespace FlaxEngine.GUI
|
||||
/// Check box control.
|
||||
/// </summary>
|
||||
/// <seealso cref="FlaxEngine.GUI.Control" />
|
||||
[ActorToolbox("GUI")]
|
||||
public class CheckBox : Control
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -9,6 +9,7 @@ namespace FlaxEngine.GUI
|
||||
/// Dropdown menu control allows to choose one item from the provided collection of options.
|
||||
/// </summary>
|
||||
/// <seealso cref="FlaxEngine.GUI.ContainerControl" />
|
||||
[ActorToolbox("GUI")]
|
||||
public class Dropdown : ContainerControl
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -8,6 +8,7 @@ namespace FlaxEngine.GUI
|
||||
/// The basic GUI image control. Shows texture, sprite or render target.
|
||||
/// </summary>
|
||||
/// <seealso cref="FlaxEngine.GUI.ContainerControl" />
|
||||
[ActorToolbox("GUI")]
|
||||
public class Image : ContainerControl
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -8,6 +8,7 @@ namespace FlaxEngine.GUI
|
||||
/// The basic GUI label control.
|
||||
/// </summary>
|
||||
/// <seealso cref="FlaxEngine.GUI.ContainerControl" />
|
||||
[ActorToolbox("GUI")]
|
||||
public class Label : ContainerControl
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -8,6 +8,7 @@ namespace FlaxEngine.GUI
|
||||
/// Progress bar control shows visual progress of the action or set of actions.
|
||||
/// </summary>
|
||||
/// <seealso cref="FlaxEngine.GUI.Control" />
|
||||
[ActorToolbox("GUI")]
|
||||
public class ProgressBar : ContainerControl
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace FlaxEngine.GUI
|
||||
/// <summary>
|
||||
/// UI container control that can render children to texture and display pre-cached texture instead of drawing children every frame. It can be also used to render part of UI to texture and use it in material or shader.
|
||||
/// </summary>
|
||||
[ActorToolbox("GUI")]
|
||||
public class RenderToTextureControl : ContainerControl
|
||||
{
|
||||
private bool _invalid, _redrawRegistered, _isDuringTextureDraw;
|
||||
|
||||
@@ -7,6 +7,7 @@ namespace FlaxEngine.GUI
|
||||
/// <summary>
|
||||
/// Rich text box control which can gather text input from the user and present text in highly formatted and stylized way.
|
||||
/// </summary>
|
||||
[ActorToolbox("GUI")]
|
||||
public partial class RichTextBox : RichTextBoxBase
|
||||
{
|
||||
private TextBlockStyle _textStyle;
|
||||
|
||||
@@ -7,6 +7,7 @@ namespace FlaxEngine.GUI;
|
||||
/// <summary>
|
||||
/// The slider control.
|
||||
/// </summary>
|
||||
[ActorToolbox("GUI")]
|
||||
public class Slider : ContainerControl
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -6,6 +6,7 @@ namespace FlaxEngine.GUI
|
||||
/// Helper control used to insert blank space into the layout.
|
||||
/// </summary>
|
||||
/// <seealso cref="FlaxEngine.GUI.ContainerControl" />
|
||||
[ActorToolbox("GUI")]
|
||||
public sealed class Spacer : ContainerControl
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace FlaxEngine.GUI
|
||||
/// <summary>
|
||||
/// Text box control which can gather text input from the user.
|
||||
/// </summary>
|
||||
[ActorToolbox("GUI")]
|
||||
public class TextBox : TextBoxBase
|
||||
{
|
||||
private TextLayoutOptions _layout;
|
||||
@@ -213,7 +214,7 @@ namespace FlaxEngine.GUI
|
||||
color *= 0.6f;
|
||||
Render2D.DrawText(font, _text, color, ref _layout, TextMaterial);
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(_watermarkText) && !IsFocused)
|
||||
else if (!string.IsNullOrEmpty(_watermarkText))
|
||||
{
|
||||
Render2D.DrawText(font, _watermarkText, WatermarkTextColor, ref _layout, TextMaterial);
|
||||
}
|
||||
|
||||
@@ -1203,7 +1203,7 @@ namespace FlaxEngine.GUI
|
||||
if (base.OnMouseDown(location, button))
|
||||
return true;
|
||||
|
||||
if (button == MouseButton.Left && _text.Length > 0 && _isSelectable)
|
||||
if (button == MouseButton.Left && _isSelectable)
|
||||
{
|
||||
Focus();
|
||||
OnSelectingBegin();
|
||||
@@ -1219,6 +1219,10 @@ namespace FlaxEngine.GUI
|
||||
else
|
||||
SetSelection(_selectionStart, hitPos);
|
||||
}
|
||||
else if (string.IsNullOrEmpty(_text))
|
||||
{
|
||||
SetSelection(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetSelection(hitPos);
|
||||
@@ -1265,7 +1269,11 @@ namespace FlaxEngine.GUI
|
||||
// Multiline scroll
|
||||
if (IsMultiline && _text.Length != 0 && IsMultilineScrollable)
|
||||
{
|
||||
TargetViewOffset = Float2.Clamp(_targetViewOffset - new Float2(0, delta * 10.0f), Float2.Zero, new Float2(_targetViewOffset.X, _textSize.Y - Height));
|
||||
if (Input.GetKey(KeyboardKeys.Shift))
|
||||
TargetViewOffset = Float2.Clamp(_targetViewOffset - new Float2(delta * 20.0f, 0), Float2.Zero, new Float2(_textSize.X, _targetViewOffset.Y));
|
||||
else
|
||||
TargetViewOffset = Float2.Clamp(_targetViewOffset - new Float2(0, delta * 10.0f), Float2.Zero, new Float2(_targetViewOffset.X, _textSize.Y - Height));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace FlaxEngine.GUI
|
||||
/// <summary>
|
||||
/// Changes alpha of all its children
|
||||
/// </summary>
|
||||
[ActorToolbox("GUI")]
|
||||
public class AlphaPanel : ContainerControl
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -6,6 +6,7 @@ namespace FlaxEngine.GUI
|
||||
/// The blur panel that applied the Gaussian-blur to all content beneath the control.
|
||||
/// </summary>
|
||||
/// <seealso cref="FlaxEngine.GUI.ContainerControl" />
|
||||
[ActorToolbox("GUI")]
|
||||
public class BlurPanel : ContainerControl
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -8,6 +8,7 @@ namespace FlaxEngine.GUI
|
||||
/// Drop Panel arranges control vertically and provides feature to collapse contents.
|
||||
/// </summary>
|
||||
/// <seealso cref="FlaxEngine.GUI.ContainerControl" />
|
||||
[ActorToolbox("GUI")]
|
||||
public class DropPanel : ContainerControl
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -8,6 +8,7 @@ namespace FlaxEngine.GUI
|
||||
/// A panel that divides up available space between all of its children.
|
||||
/// </summary>
|
||||
/// <seealso cref="FlaxEngine.GUI.ContainerControl" />
|
||||
[ActorToolbox("GUI")]
|
||||
public class GridPanel : ContainerControl
|
||||
{
|
||||
private Margin _slotPadding;
|
||||
|
||||
@@ -6,6 +6,7 @@ namespace FlaxEngine.GUI
|
||||
/// This panel arranges child controls horizontally.
|
||||
/// </summary>
|
||||
/// <seealso cref="FlaxEngine.GUI.PanelWithMargins" />
|
||||
[ActorToolbox("GUI")]
|
||||
public class HorizontalPanel : PanelWithMargins
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -8,6 +8,7 @@ namespace FlaxEngine.GUI
|
||||
/// Panel UI control.
|
||||
/// </summary>
|
||||
/// <seealso cref="FlaxEngine.GUI.ScrollableControl" />
|
||||
[ActorToolbox("GUI")]
|
||||
public class Panel : ScrollableControl
|
||||
{
|
||||
private bool _layoutChanged;
|
||||
@@ -291,11 +292,15 @@ namespace FlaxEngine.GUI
|
||||
if (base.OnMouseWheel(location, delta))
|
||||
return true;
|
||||
|
||||
if (Input.GetKey(KeyboardKeys.Shift))
|
||||
{
|
||||
if (HScrollBar != null && HScrollBar.Enabled && HScrollBar.OnMouseWheel(HScrollBar.PointFromParent(ref location), delta))
|
||||
return true;
|
||||
}
|
||||
|
||||
// Roll back to scroll bars
|
||||
if (VScrollBar != null && VScrollBar.Enabled && VScrollBar.OnMouseWheel(VScrollBar.PointFromParent(ref location), delta))
|
||||
return true;
|
||||
if (HScrollBar != null && HScrollBar.Enabled && HScrollBar.OnMouseWheel(HScrollBar.PointFromParent(ref location), delta))
|
||||
return true;
|
||||
|
||||
// No event handled
|
||||
return false;
|
||||
|
||||
@@ -8,6 +8,7 @@ namespace FlaxEngine.GUI
|
||||
/// Panel that arranges child controls like tiles.
|
||||
/// </summary>
|
||||
/// <seealso cref="FlaxEngine.GUI.ContainerControl" />
|
||||
[ActorToolbox("GUI")]
|
||||
public class TilesPanel : ContainerControl
|
||||
{
|
||||
private Margin _tileMargin;
|
||||
|
||||
@@ -6,6 +6,7 @@ namespace FlaxEngine.GUI
|
||||
/// A panel that evenly divides up available space between all of its children.
|
||||
/// </summary>
|
||||
/// <seealso cref="FlaxEngine.GUI.ContainerControl" />
|
||||
[ActorToolbox("GUI")]
|
||||
public class UniformGridPanel : ContainerControl
|
||||
{
|
||||
private Margin _slotPadding;
|
||||
|
||||
@@ -6,6 +6,7 @@ namespace FlaxEngine.GUI
|
||||
/// This panel arranges child controls vertically.
|
||||
/// </summary>
|
||||
/// <seealso cref="FlaxEngine.GUI.PanelWithMargins" />
|
||||
[ActorToolbox("GUI")]
|
||||
public class VerticalPanel : PanelWithMargins
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
/// <summary>
|
||||
/// Sprite rendering object.
|
||||
/// </summary>
|
||||
API_CLASS(Attributes="ActorContextMenu(\"New/UI/Sprite Render\"), ActorToolbox(\"GUI\")")
|
||||
API_CLASS(Attributes="ActorContextMenu(\"New/UI/Sprite Render\"), ActorToolbox(\"Visuals\")")
|
||||
class FLAXENGINE_API SpriteRender : public Actor
|
||||
{
|
||||
DECLARE_SCENE_OBJECT(SpriteRender);
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
/// <summary>
|
||||
/// Text rendering object.
|
||||
/// </summary>
|
||||
API_CLASS(Attributes="ActorContextMenu(\"New/UI/Text Render\"), ActorToolbox(\"GUI\")")
|
||||
API_CLASS(Attributes="ActorContextMenu(\"New/UI/Text Render\"), ActorToolbox(\"Visuals\")")
|
||||
class FLAXENGINE_API TextRender : public Actor
|
||||
{
|
||||
DECLARE_SCENE_OBJECT(TextRender);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
/// <summary>
|
||||
/// Contains a single GUI control (on C# side).
|
||||
/// </summary>
|
||||
API_CLASS(Sealed, Attributes="ActorContextMenu(\"New/UI/UI Control\"), ActorToolbox(\"GUI\")")
|
||||
API_CLASS(Sealed, Attributes="ActorContextMenu(\"New/UI/UI Control\"), ActorToolbox(\"GUI\", \"Empty UIControl\")")
|
||||
class FLAXENGINE_API UIControl : public Actor
|
||||
{
|
||||
DECLARE_SCENE_OBJECT(UIControl);
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
apply plugin: 'com.android.application'
|
||||
android {
|
||||
compileSdkVersion 24
|
||||
compileSdk ${TargetSdk}
|
||||
namespace "${PackageName}"
|
||||
defaultConfig {
|
||||
applicationId "${PackageName}"
|
||||
minSdkVersion 24
|
||||
targetSdkVersion 24
|
||||
versionCode 1
|
||||
minSdk ${MinimumSdk}
|
||||
targetSdk ${TargetSdk}
|
||||
versionCode ${VersionCode}
|
||||
versionName "${ProjectVersion}"
|
||||
ndk {
|
||||
abiFilter "${PackageAbi}"
|
||||
|
||||
@@ -5,9 +5,13 @@
|
||||
<application android:label="@string/app_name"${AndroidAttributes}
|
||||
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
|
||||
android:icon="@mipmap/icon"
|
||||
android:appCategory="game"
|
||||
android:isGame="true"
|
||||
android:hasFragileUserData="false"
|
||||
android:extractNativeLibs="true"
|
||||
android:hasCode="true">
|
||||
<activity android:name="com.flaxengine.GameActivity"
|
||||
android:exported="true"
|
||||
android:label="@string/app_name"
|
||||
android:configChanges="orientation|keyboardHidden|screenSize"
|
||||
android:screenOrientation="${DefaultOrientation}">
|
||||
|
||||
Reference in New Issue
Block a user