Merge branch 'FlaxEngine:master' into terrainscripting
This commit is contained in:
2
.github/workflows/build_android.yml
vendored
2
.github/workflows/build_android.yml
vendored
@@ -33,4 +33,4 @@ jobs:
|
|||||||
git lfs pull
|
git lfs pull
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
.\Development\Scripts\Windows\CallBuildTool.bat -build -log -printSDKs -arch=ARM64 -platform=Android -configuration=Release -buildtargets=FlaxGame
|
.\Development\Scripts\Windows\CallBuildTool.bat -build -log -printSDKs -dotnet=7 -arch=ARM64 -platform=Android -configuration=Release -buildtargets=FlaxGame
|
||||||
|
|||||||
2
.github/workflows/build_ios.yml
vendored
2
.github/workflows/build_ios.yml
vendored
@@ -33,4 +33,4 @@ jobs:
|
|||||||
git lfs pull
|
git lfs pull
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
./Development/Scripts/Mac/CallBuildTool.sh -build -log -arch=ARM64 -platform=iOS -configuration=Release -buildtargets=FlaxGame
|
./Development/Scripts/Mac/CallBuildTool.sh -build -log -dotnet=7 -arch=ARM64 -platform=iOS -configuration=Release -buildtargets=FlaxGame
|
||||||
|
|||||||
4
.github/workflows/build_linux.yml
vendored
4
.github/workflows/build_linux.yml
vendored
@@ -36,7 +36,7 @@ jobs:
|
|||||||
git lfs pull
|
git lfs pull
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
./Development/Scripts/Linux/CallBuildTool.sh -build -log -printSDKs -arch=x64 -platform=Linux -configuration=Development -buildtargets=FlaxEditor
|
./Development/Scripts/Linux/CallBuildTool.sh -build -log -printSDKs -dotnet=7 -arch=x64 -platform=Linux -configuration=Development -buildtargets=FlaxEditor
|
||||||
|
|
||||||
# Game
|
# Game
|
||||||
game-linux:
|
game-linux:
|
||||||
@@ -64,4 +64,4 @@ jobs:
|
|||||||
git lfs pull
|
git lfs pull
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
./Development/Scripts/Linux/CallBuildTool.sh -build -log -printSDKs -arch=x64 -platform=Linux -configuration=Release -buildtargets=FlaxGame
|
./Development/Scripts/Linux/CallBuildTool.sh -build -log -printSDKs -dotnet=7 -arch=x64 -platform=Linux -configuration=Release -buildtargets=FlaxGame
|
||||||
|
|||||||
4
.github/workflows/build_mac.yml
vendored
4
.github/workflows/build_mac.yml
vendored
@@ -30,7 +30,7 @@ jobs:
|
|||||||
git lfs pull
|
git lfs pull
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
./Development/Scripts/Mac/CallBuildTool.sh -build -log -printSDKs -arch=x64 -platform=Mac -configuration=Development -buildtargets=FlaxEditor
|
./Development/Scripts/Mac/CallBuildTool.sh -build -log -printSDKs -dotnet=7 -arch=x64 -platform=Mac -configuration=Development -buildtargets=FlaxEditor
|
||||||
|
|
||||||
# Game
|
# Game
|
||||||
game-mac:
|
game-mac:
|
||||||
@@ -55,4 +55,4 @@ jobs:
|
|||||||
git lfs pull
|
git lfs pull
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
./Development/Scripts/Mac/CallBuildTool.sh -build -log -printSDKs -arch=x64 -platform=Mac -configuration=Release -buildtargets=FlaxGame
|
./Development/Scripts/Mac/CallBuildTool.sh -build -log -printSDKs -dotnet=7 -arch=x64 -platform=Mac -configuration=Release -buildtargets=FlaxGame
|
||||||
|
|||||||
4
.github/workflows/build_windows.yml
vendored
4
.github/workflows/build_windows.yml
vendored
@@ -30,7 +30,7 @@ jobs:
|
|||||||
git lfs pull
|
git lfs pull
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
.\Development\Scripts\Windows\CallBuildTool.bat -build -log -printSDKs -arch=x64 -platform=Windows -configuration=Development -buildtargets=FlaxEditor
|
.\Development\Scripts\Windows\CallBuildTool.bat -build -log -printSDKs -dotnet=7 -arch=x64 -platform=Windows -configuration=Development -buildtargets=FlaxEditor
|
||||||
|
|
||||||
# Game
|
# Game
|
||||||
game-windows:
|
game-windows:
|
||||||
@@ -55,4 +55,4 @@ jobs:
|
|||||||
git lfs pull
|
git lfs pull
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
.\Development\Scripts\Windows\CallBuildTool.bat -build -log -printSDKs -arch=x64 -platform=Windows -configuration=Release -buildtargets=FlaxGame
|
.\Development\Scripts\Windows\CallBuildTool.bat -build -log -printSDKs -dotnet=7 -arch=x64 -platform=Windows -configuration=Release -buildtargets=FlaxGame
|
||||||
|
|||||||
10
.github/workflows/tests.yml
vendored
10
.github/workflows/tests.yml
vendored
@@ -34,8 +34,8 @@ jobs:
|
|||||||
sudo apt-get install libx11-dev libxcursor-dev libxinerama-dev build-essential gettext libtool libtool-bin libpulse-dev libasound2-dev libjack-dev portaudio19-dev
|
sudo apt-get install libx11-dev libxcursor-dev libxinerama-dev build-essential gettext libtool libtool-bin libpulse-dev libasound2-dev libjack-dev portaudio19-dev
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
./GenerateProjectFiles.sh -vs2022 -log -verbose -printSDKs
|
./GenerateProjectFiles.sh -vs2022 -log -verbose -printSDKs -dotnet=7
|
||||||
./Development/Scripts/Linux/CallBuildTool.sh -build -log -arch=x64 -platform=Linux -configuration=Development -buildtargets=FlaxTestsTarget
|
./Development/Scripts/Linux/CallBuildTool.sh -build -log -dotnet=7 -arch=x64 -platform=Linux -configuration=Development -buildtargets=FlaxTestsTarget
|
||||||
dotnet msbuild Source/Tools/Flax.Build.Tests/Flax.Build.Tests.csproj /m /t:Restore,Build /p:Configuration=Debug /p:Platform=AnyCPU /nologo
|
dotnet msbuild Source/Tools/Flax.Build.Tests/Flax.Build.Tests.csproj /m /t:Restore,Build /p:Configuration=Debug /p:Platform=AnyCPU /nologo
|
||||||
dotnet msbuild Source/Tools/Flax.Build.Tests/Flax.Build.Tests.csproj /m /t:Restore,Build /p:Configuration=Debug /p:Platform=AnyCPU /nologo
|
dotnet msbuild Source/Tools/Flax.Build.Tests/Flax.Build.Tests.csproj /m /t:Restore,Build /p:Configuration=Debug /p:Platform=AnyCPU /nologo
|
||||||
- name: Test
|
- name: Test
|
||||||
@@ -48,7 +48,7 @@ jobs:
|
|||||||
dotnet test -f net7.0 Binaries/Tests/FlaxEngine.CSharp.dll
|
dotnet test -f net7.0 Binaries/Tests/FlaxEngine.CSharp.dll
|
||||||
- name: Test UseLargeWorlds
|
- name: Test UseLargeWorlds
|
||||||
run: |
|
run: |
|
||||||
./Development/Scripts/Linux/CallBuildTool.sh -build -log -arch=x64 -platform=Linux -configuration=Development -buildtargets=FlaxTestsTarget -UseLargeWorlds=true
|
./Development/Scripts/Linux/CallBuildTool.sh -build -log -dotnet=7 -arch=x64 -platform=Linux -configuration=Development -buildtargets=FlaxTestsTarget -UseLargeWorlds=true
|
||||||
${GITHUB_WORKSPACE}/Binaries/Editor/Linux/Development/FlaxTests
|
${GITHUB_WORKSPACE}/Binaries/Editor/Linux/Development/FlaxTests
|
||||||
|
|
||||||
# Tests on Windows
|
# Tests on Windows
|
||||||
@@ -72,8 +72,8 @@ jobs:
|
|||||||
git lfs pull
|
git lfs pull
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
.\GenerateProjectFiles.bat -vs2022 -log -verbose -printSDKs
|
.\GenerateProjectFiles.bat -vs2022 -log -verbose -printSDKs -dotnet=7
|
||||||
.\Development\Scripts\Windows\CallBuildTool.bat -build -log -arch=x64 -platform=Windows -configuration=Development -buildtargets=FlaxTestsTarget
|
.\Development\Scripts\Windows\CallBuildTool.bat -build -log -dotnet=7 -arch=x64 -platform=Windows -configuration=Development -buildtargets=FlaxTestsTarget
|
||||||
dotnet msbuild Source\Tools\Flax.Build.Tests\Flax.Build.Tests.csproj /m /t:Restore,Build /p:Configuration=Debug /p:Platform=AnyCPU /nologo
|
dotnet msbuild Source\Tools\Flax.Build.Tests\Flax.Build.Tests.csproj /m /t:Restore,Build /p:Configuration=Debug /p:Platform=AnyCPU /nologo
|
||||||
- name: Test
|
- name: Test
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -12,6 +12,7 @@ Source/*.csproj
|
|||||||
/Package_*/
|
/Package_*/
|
||||||
!Source/Engine/Debug
|
!Source/Engine/Debug
|
||||||
/Source/Platforms/Editor/Linux/Mono/etc/mono/registry
|
/Source/Platforms/Editor/Linux/Mono/etc/mono/registry
|
||||||
|
PackageEditor_Cert.command
|
||||||
PackageEditor_Cert.bat
|
PackageEditor_Cert.bat
|
||||||
PackagePlatforms_Cert.bat
|
PackagePlatforms_Cert.bat
|
||||||
|
|
||||||
|
|||||||
BIN
Content/Editor/DebugMaterials/DDGIDebugProbes.flax
(Stored with Git LFS)
BIN
Content/Editor/DebugMaterials/DDGIDebugProbes.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/DebugMaterials/SingleColor/Particle.flax
(Stored with Git LFS)
BIN
Content/Editor/DebugMaterials/SingleColor/Particle.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/DebugMaterials/SingleColor/SurfaceAdditive.flax
(Stored with Git LFS)
BIN
Content/Editor/DebugMaterials/SingleColor/SurfaceAdditive.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Gizmo/FoliageBrushMaterial.flax
(Stored with Git LFS)
BIN
Content/Editor/Gizmo/FoliageBrushMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Particles/Constant Burst.flax
(Stored with Git LFS)
BIN
Content/Editor/Particles/Constant Burst.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Particles/Periodic Burst.flax
(Stored with Git LFS)
BIN
Content/Editor/Particles/Periodic Burst.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Particles/Smoke.flax
(Stored with Git LFS)
BIN
Content/Editor/Particles/Smoke.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Particles/Sparks.flax
(Stored with Git LFS)
BIN
Content/Editor/Particles/Sparks.flax
(Stored with Git LFS)
Binary file not shown.
@@ -33,4 +33,3 @@ public class %class% : Script
|
|||||||
// Here you can add code that needs to be called every frame
|
// Here you can add code that needs to be called every frame
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
BIN
Content/Editor/Terrain/Circle Brush Material.flax
(Stored with Git LFS)
BIN
Content/Editor/Terrain/Circle Brush Material.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Shaders/GlobalSignDistanceField.flax
(Stored with Git LFS)
BIN
Content/Shaders/GlobalSignDistanceField.flax
(Stored with Git LFS)
Binary file not shown.
@@ -3,7 +3,8 @@
|
|||||||
"Version": {
|
"Version": {
|
||||||
"Major": 1,
|
"Major": 1,
|
||||||
"Minor": 7,
|
"Minor": 7,
|
||||||
"Build": 6401
|
"Revision": 1,
|
||||||
|
"Build": 6406
|
||||||
},
|
},
|
||||||
"Company": "Flax",
|
"Company": "Flax",
|
||||||
"Copyright": "Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.",
|
"Copyright": "Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.",
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ if errorlevel 1 goto BuildToolFailed
|
|||||||
|
|
||||||
:: Build bindings for all editor configurations
|
:: Build bindings for all editor configurations
|
||||||
echo Building C# bindings...
|
echo Building C# bindings...
|
||||||
Binaries\Tools\Flax.Build.exe -build -BuildBindingsOnly -arch=x64 -platform=Windows --buildTargets=FlaxEditor,FlaxGame
|
Binaries\Tools\Flax.Build.exe -build -BuildBindingsOnly -arch=x64 -platform=Windows --buildTargets=FlaxEditor
|
||||||
|
|
||||||
popd
|
popd
|
||||||
echo Done!
|
echo Done!
|
||||||
|
|||||||
@@ -14,4 +14,4 @@ bash ./Development/Scripts/Mac/CallBuildTool.sh --genproject "$@"
|
|||||||
# Build bindings for all editor configurations
|
# Build bindings for all editor configurations
|
||||||
echo Building C# bindings...
|
echo Building C# bindings...
|
||||||
# TODO: Detect the correct architecture here
|
# TODO: Detect the correct architecture here
|
||||||
Binaries/Tools/Flax.Build -build -BuildBindingsOnly -arch=ARM64 -platform=Mac --buildTargets=FlaxEditor,FlaxGame
|
Binaries/Tools/Flax.Build -build -BuildBindingsOnly -arch=ARM64 -platform=Mac --buildTargets=FlaxEditor
|
||||||
|
|||||||
@@ -14,4 +14,4 @@ bash ./Development/Scripts/Linux/CallBuildTool.sh --genproject "$@"
|
|||||||
# Build bindings for all editor configurations
|
# Build bindings for all editor configurations
|
||||||
echo Building C# bindings...
|
echo Building C# bindings...
|
||||||
# TODO: Detect the correct architecture here
|
# TODO: Detect the correct architecture here
|
||||||
Binaries/Tools/Flax.Build -build -BuildBindingsOnly -arch=x64 -platform=Linux --buildTargets=FlaxEditor,FlaxGame
|
Binaries/Tools/Flax.Build -build -BuildBindingsOnly -arch=x64 -platform=Linux --buildTargets=FlaxEditor
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ pushd
|
|||||||
echo Performing the full package...
|
echo Performing the full package...
|
||||||
|
|
||||||
rem Run the build tool.
|
rem Run the build tool.
|
||||||
call "Development\Scripts\Windows\CallBuildTool.bat" -deploy -deployEditor -deployPlatforms -verbose -log -logFile="Cache\Intermediate\PackageLog.txt" %*
|
call "Development\Scripts\Windows\CallBuildTool.bat" -deploy -deployEditor -deployPlatforms -dotnet=7 -verbose -log -logFile="Cache\Intermediate\PackageLog.txt" %*
|
||||||
if errorlevel 1 goto BuildToolFailed
|
if errorlevel 1 goto BuildToolFailed
|
||||||
|
|
||||||
popd
|
popd
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ pushd
|
|||||||
echo Building and packaging Flax Editor...
|
echo Building and packaging Flax Editor...
|
||||||
|
|
||||||
rem Run the build tool.
|
rem Run the build tool.
|
||||||
call "Development\Scripts\Windows\CallBuildTool.bat" -deploy -deployEditor -verbose -log -logFile="Cache\Intermediate\PackageLog.txt" %*
|
call "Development\Scripts\Windows\CallBuildTool.bat" -deploy -deployEditor -dotnet=7 -verbose -log -logFile="Cache\Intermediate\PackageLog.txt" %*
|
||||||
if errorlevel 1 goto BuildToolFailed
|
if errorlevel 1 goto BuildToolFailed
|
||||||
|
|
||||||
popd
|
popd
|
||||||
|
|||||||
@@ -9,4 +9,4 @@ echo Building and packaging Flax Editor...
|
|||||||
cd "`dirname "$0"`"
|
cd "`dirname "$0"`"
|
||||||
|
|
||||||
# Run Flax.Build (also pass the arguments)
|
# Run Flax.Build (also pass the arguments)
|
||||||
bash ./Development/Scripts/Mac/CallBuildTool.sh --deploy --deployEditor --verbose --log --logFile="Cache/Intermediate/PackageLog.txt" "$@"
|
bash ./Development/Scripts/Mac/CallBuildTool.sh --deploy --deployEditor --dotnet=7 --verbose --log --logFile="Cache/Intermediate/PackageLog.txt" "$@"
|
||||||
|
|||||||
@@ -9,4 +9,4 @@ echo Building and packaging Flax Editor...
|
|||||||
cd "`dirname "$0"`"
|
cd "`dirname "$0"`"
|
||||||
|
|
||||||
# Run Flax.Build (also pass the arguments)
|
# Run Flax.Build (also pass the arguments)
|
||||||
bash ./Development/Scripts/Linux/CallBuildTool.sh --deploy --deployEditor --verbose --log --logFile="Cache/Intermediate/PackageLog.txt" "$@"
|
bash ./Development/Scripts/Linux/CallBuildTool.sh --deploy --deployEditor --dotnet=7 --verbose --log --logFile="Cache/Intermediate/PackageLog.txt" "$@"
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ pushd
|
|||||||
echo Building and packaging platforms data...
|
echo Building and packaging platforms data...
|
||||||
|
|
||||||
rem Run the build tool.
|
rem Run the build tool.
|
||||||
call "Development\Scripts\Windows\CallBuildTool.bat" -deploy -deployPlatforms -verbose -log -logFile="Cache\Intermediate\PackageLog.txt" %*
|
call "Development\Scripts\Windows\CallBuildTool.bat" -deploy -deployPlatforms -dotnet=7 -verbose -log -logFile="Cache\Intermediate\PackageLog.txt" %*
|
||||||
if errorlevel 1 goto BuildToolFailed
|
if errorlevel 1 goto BuildToolFailed
|
||||||
|
|
||||||
popd
|
popd
|
||||||
|
|||||||
@@ -9,4 +9,4 @@ echo Building and packaging platforms data...
|
|||||||
cd "`dirname "$0"`"
|
cd "`dirname "$0"`"
|
||||||
|
|
||||||
# Run Flax.Build (also pass the arguments)
|
# Run Flax.Build (also pass the arguments)
|
||||||
bash ./Development/Scripts/Mac/CallBuildTool.sh --deploy --deployPlatforms --verbose --log --logFile="Cache/Intermediate/PackageLog.txt" "$@"
|
bash ./Development/Scripts/Mac/CallBuildTool.sh --deploy --deployPlatforms --dotnet=7 --verbose --log --logFile="Cache/Intermediate/PackageLog.txt" "$@"
|
||||||
|
|||||||
@@ -9,4 +9,4 @@ echo Building and packaging platforms data...
|
|||||||
cd "`dirname "$0"`"
|
cd "`dirname "$0"`"
|
||||||
|
|
||||||
# Run Flax.Build (also pass the arguments)
|
# Run Flax.Build (also pass the arguments)
|
||||||
bash ./Development/Scripts/Linux/CallBuildTool.sh --deploy --deployPlatforms --verbose --log --logFile="Cache/Intermediate/PackageLog.txt" "$@"
|
bash ./Development/Scripts/Linux/CallBuildTool.sh --deploy --deployPlatforms --dotnet=7 --verbose --log --logFile="Cache/Intermediate/PackageLog.txt" "$@"
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<a href="https://flaxengine.com/discord"><img src="https://discordapp.com/api/guilds/437989205315158016/widget.png"/></a>
|
<a href="https://flaxengine.com/discord"><img src="https://discordapp.com/api/guilds/437989205315158016/widget.png"/></a>
|
||||||
|
|
||||||
Flax Engine is a high quality modern 3D game engine written in C++ and C#.
|
Flax Engine is a high quality modern 3D game engine written in C++ and C#.
|
||||||
From stunning graphics to powerful scripts - Flax can give everything for your games. Designed for fast workflow with many ready to use features waiting for you right now. To learn more see the website ([www.flaxengine.com](https://flaxengine.com)).
|
From stunning graphics to powerful scripts, it's designed for fast workflow with many ready-to-use features waiting for you right now. To learn more see the website ([www.flaxengine.com](https://flaxengine.com)).
|
||||||
|
|
||||||
This repository contains full source code of the Flax Engine (excluding NDA-protected platforms support). Anyone is welcome to contribute or use the modified source in Flax-based games.
|
This repository contains full source code of the Flax Engine (excluding NDA-protected platforms support). Anyone is welcome to contribute or use the modified source in Flax-based games.
|
||||||
|
|
||||||
|
|||||||
292
Source/Editor/Content/AssetPickerValidator.cs
Normal file
292
Source/Editor/Content/AssetPickerValidator.cs
Normal file
@@ -0,0 +1,292 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using FlaxEditor.Scripting;
|
||||||
|
using FlaxEngine;
|
||||||
|
using FlaxEngine.Utilities;
|
||||||
|
|
||||||
|
namespace FlaxEditor.Content;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Manages and converts the selected content item to the appropriate types. Useful for drag operations.
|
||||||
|
/// </summary>
|
||||||
|
public class AssetPickerValidator : IContentItemOwner
|
||||||
|
{
|
||||||
|
private Asset _selected;
|
||||||
|
private ContentItem _selectedItem;
|
||||||
|
private ScriptType _type;
|
||||||
|
private string _fileExtension;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the selected item.
|
||||||
|
/// </summary>
|
||||||
|
public ContentItem SelectedItem
|
||||||
|
{
|
||||||
|
get => _selectedItem;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_selectedItem == value)
|
||||||
|
return;
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
if (_selected == null && _selectedItem is SceneItem)
|
||||||
|
{
|
||||||
|
// Deselect scene reference
|
||||||
|
_selectedItem.RemoveReference(this);
|
||||||
|
_selectedItem = null;
|
||||||
|
_selected = null;
|
||||||
|
OnSelectedItemChanged();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deselect
|
||||||
|
_selectedItem?.RemoveReference(this);
|
||||||
|
_selectedItem = null;
|
||||||
|
_selected = null;
|
||||||
|
OnSelectedItemChanged();
|
||||||
|
}
|
||||||
|
else if (value is SceneItem item)
|
||||||
|
{
|
||||||
|
if (_selectedItem == item)
|
||||||
|
return;
|
||||||
|
if (!IsValid(item))
|
||||||
|
item = null;
|
||||||
|
|
||||||
|
// Change value to scene reference (cannot load asset because scene can be already loaded - duplicated ID issue)
|
||||||
|
_selectedItem?.RemoveReference(this);
|
||||||
|
_selectedItem = item;
|
||||||
|
_selected = null;
|
||||||
|
_selectedItem?.AddReference(this);
|
||||||
|
OnSelectedItemChanged();
|
||||||
|
}
|
||||||
|
else if (value is AssetItem assetItem)
|
||||||
|
{
|
||||||
|
SelectedAsset = FlaxEngine.Content.LoadAsync(assetItem.ID);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Change value
|
||||||
|
_selectedItem?.RemoveReference(this);
|
||||||
|
_selectedItem = value;
|
||||||
|
_selected = null;
|
||||||
|
OnSelectedItemChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the selected asset identifier.
|
||||||
|
/// </summary>
|
||||||
|
public Guid SelectedID
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_selected != null)
|
||||||
|
return _selected.ID;
|
||||||
|
if (_selectedItem is AssetItem assetItem)
|
||||||
|
return assetItem.ID;
|
||||||
|
return Guid.Empty;
|
||||||
|
}
|
||||||
|
set => SelectedItem = Editor.Instance.ContentDatabase.FindAsset(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the selected content item path.
|
||||||
|
/// </summary>
|
||||||
|
public string SelectedPath
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
string path = _selectedItem?.Path ?? _selected?.Path;
|
||||||
|
if (path != null)
|
||||||
|
{
|
||||||
|
// Convert into path relative to the project (cross-platform)
|
||||||
|
var projectFolder = Globals.ProjectFolder;
|
||||||
|
if (path.StartsWith(projectFolder))
|
||||||
|
path = path.Substring(projectFolder.Length + 1);
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(value))
|
||||||
|
{
|
||||||
|
SelectedItem = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var path = StringUtils.IsRelative(value) ? Path.Combine(Globals.ProjectFolder, value) : value;
|
||||||
|
SelectedItem = Editor.Instance.ContentDatabase.Find(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the selected asset object.
|
||||||
|
/// </summary>
|
||||||
|
public Asset SelectedAsset
|
||||||
|
{
|
||||||
|
get => _selected;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
// Check if value won't change
|
||||||
|
if (value == _selected)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Find item from content database and check it
|
||||||
|
var item = value ? Editor.Instance.ContentDatabase.FindAsset(value.ID) : null;
|
||||||
|
if (item != null && !IsValid(item))
|
||||||
|
item = null;
|
||||||
|
|
||||||
|
// Change value
|
||||||
|
_selectedItem?.RemoveReference(this);
|
||||||
|
_selectedItem = item;
|
||||||
|
_selected = value;
|
||||||
|
_selectedItem?.AddReference(this);
|
||||||
|
OnSelectedItemChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the assets types that this picker accepts (it supports types derived from the given type). Use <see cref="ScriptType.Null"/> for generic file picker.
|
||||||
|
/// </summary>
|
||||||
|
public ScriptType AssetType
|
||||||
|
{
|
||||||
|
get => _type;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_type != value)
|
||||||
|
{
|
||||||
|
_type = value;
|
||||||
|
|
||||||
|
// Auto deselect if the current value is invalid
|
||||||
|
if (_selectedItem != null && !IsValid(_selectedItem))
|
||||||
|
SelectedItem = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the content items extensions filter. Null if unused.
|
||||||
|
/// </summary>
|
||||||
|
public string FileExtension
|
||||||
|
{
|
||||||
|
get => _fileExtension;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_fileExtension != value)
|
||||||
|
{
|
||||||
|
_fileExtension = value;
|
||||||
|
|
||||||
|
// Auto deselect if the current value is invalid
|
||||||
|
if (_selectedItem != null && !IsValid(_selectedItem))
|
||||||
|
SelectedItem = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs when selected item gets changed.
|
||||||
|
/// </summary>
|
||||||
|
public event Action SelectedItemChanged;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The custom callback for assets validation. Cane be used to implement a rule for assets to pick.
|
||||||
|
/// </summary>
|
||||||
|
public Func<ContentItem, bool> CheckValid;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns whether item is valid.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="item"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool IsValid(ContentItem item)
|
||||||
|
{
|
||||||
|
if (_fileExtension != null && !item.Path.EndsWith(_fileExtension))
|
||||||
|
return false;
|
||||||
|
if (CheckValid != null && !CheckValid(item))
|
||||||
|
return false;
|
||||||
|
if (_type == ScriptType.Null)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (item is AssetItem assetItem)
|
||||||
|
{
|
||||||
|
// Faster path for binary items (in-built)
|
||||||
|
if (assetItem is BinaryAssetItem binaryItem)
|
||||||
|
return _type.IsAssignableFrom(new ScriptType(binaryItem.Type));
|
||||||
|
|
||||||
|
// Type filter
|
||||||
|
var type = TypeUtils.GetType(assetItem.TypeName);
|
||||||
|
if (_type.IsAssignableFrom(type))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Json assets can contain any type of the object defined by the C# type (data oriented design)
|
||||||
|
if (assetItem is JsonAssetItem && (_type.Type == typeof(JsonAsset) || _type.Type == typeof(Asset)))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Special case for scene asset references
|
||||||
|
if (_type.Type == typeof(SceneReference) && assetItem is SceneItem)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="AssetPickerValidator"/> class.
|
||||||
|
/// </summary>
|
||||||
|
public AssetPickerValidator()
|
||||||
|
: this(new ScriptType(typeof(Asset)))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="AssetPickerValidator"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="assetType">The assets types that this picker accepts.</param>
|
||||||
|
public AssetPickerValidator(ScriptType assetType)
|
||||||
|
{
|
||||||
|
_type = assetType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called when selected item gets changed.
|
||||||
|
/// </summary>
|
||||||
|
protected virtual void OnSelectedItemChanged()
|
||||||
|
{
|
||||||
|
SelectedItemChanged?.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void OnItemDeleted(ContentItem item)
|
||||||
|
{
|
||||||
|
// Deselect item
|
||||||
|
SelectedItem = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void OnItemRenamed(ContentItem item)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void OnItemReimported(ContentItem item)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void OnItemDispose(ContentItem item)
|
||||||
|
{
|
||||||
|
// Deselect item
|
||||||
|
SelectedItem = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Call to remove reference from the selected item.
|
||||||
|
/// </summary>
|
||||||
|
public void OnDestroy()
|
||||||
|
{
|
||||||
|
_selectedItem?.RemoveReference(this);
|
||||||
|
_selectedItem = null;
|
||||||
|
_selected = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,6 +24,16 @@ namespace FlaxEditor.Content
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
protected ContentFolder _folder;
|
protected ContentFolder _folder;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether this node can be deleted.
|
||||||
|
/// </summary>
|
||||||
|
public virtual bool CanDelete => true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether this node can be duplicated.
|
||||||
|
/// </summary>
|
||||||
|
public virtual bool CanDuplicate => true;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the content folder item.
|
/// Gets the content folder item.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -86,6 +96,7 @@ namespace FlaxEditor.Content
|
|||||||
Folder.ParentFolder = parent.Folder;
|
Folder.ParentFolder = parent.Folder;
|
||||||
Parent = parent;
|
Parent = parent;
|
||||||
}
|
}
|
||||||
|
IconColor = Style.Current.Foreground;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -300,7 +311,7 @@ namespace FlaxEditor.Content
|
|||||||
StartRenaming();
|
StartRenaming();
|
||||||
return true;
|
return true;
|
||||||
case KeyboardKeys.Delete:
|
case KeyboardKeys.Delete:
|
||||||
if (Folder.Exists)
|
if (Folder.Exists && CanDelete)
|
||||||
Editor.Instance.Windows.ContentWin.Delete(Folder);
|
Editor.Instance.Windows.ContentWin.Delete(Folder);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -309,7 +320,7 @@ namespace FlaxEditor.Content
|
|||||||
switch (key)
|
switch (key)
|
||||||
{
|
{
|
||||||
case KeyboardKeys.D:
|
case KeyboardKeys.D:
|
||||||
if (Folder.Exists)
|
if (Folder.Exists && CanDuplicate)
|
||||||
Editor.Instance.Windows.ContentWin.Duplicate(Folder);
|
Editor.Instance.Windows.ContentWin.Duplicate(Folder);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,12 @@ namespace FlaxEditor.Content
|
|||||||
{
|
{
|
||||||
private FileSystemWatcher _watcher;
|
private FileSystemWatcher _watcher;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override bool CanDelete => false;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override bool CanDuplicate => false;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="MainContentTreeNode"/> class.
|
/// Initializes a new instance of the <see cref="MainContentTreeNode"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -12,6 +12,13 @@
|
|||||||
class GameCooker;
|
class GameCooker;
|
||||||
class PlatformTools;
|
class PlatformTools;
|
||||||
|
|
||||||
|
#if OFFICIAL_BUILD
|
||||||
|
// Use the fixed .NET SDK version in packaged builds for compatibility (FlaxGame is precompiled with it)
|
||||||
|
#define GAME_BUILD_DOTNET_VER TEXT("-dotnet=7")
|
||||||
|
#else
|
||||||
|
#define GAME_BUILD_DOTNET_VER TEXT("")
|
||||||
|
#endif
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Game building options. Used as flags.
|
/// Game building options. Used as flags.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -280,9 +280,16 @@ bool AndroidPlatformTools::OnPostProcess(CookingData& data)
|
|||||||
const Char* gradlew = TEXT("gradlew");
|
const Char* gradlew = TEXT("gradlew");
|
||||||
#endif
|
#endif
|
||||||
#if PLATFORM_LINUX
|
#if PLATFORM_LINUX
|
||||||
Platform::RunProcess(String::Format(TEXT("chmod +x \"{0}/gradlew\""), data.OriginalOutputPath), data.OriginalOutputPath, Dictionary<String, String>(), true);
|
{
|
||||||
|
CreateProcessSettings procSettings;
|
||||||
|
procSettings.FileName = String::Format(TEXT("chmod +x \"{0}/gradlew\""), data.OriginalOutputPath);
|
||||||
|
procSettings.WorkingDirectory = data.OriginalOutputPath;
|
||||||
|
procSettings.HiddenWindow = true;
|
||||||
|
Platform::CreateProcess(procSettings);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
const bool distributionPackage = buildSettings->ForDistribution;
|
const bool distributionPackage = buildSettings->ForDistribution;
|
||||||
|
{
|
||||||
CreateProcessSettings procSettings;
|
CreateProcessSettings procSettings;
|
||||||
procSettings.FileName = String::Format(TEXT("\"{0}\" {1}"), data.OriginalOutputPath / gradlew, distributionPackage ? TEXT("assemble") : TEXT("assembleDebug"));
|
procSettings.FileName = String::Format(TEXT("\"{0}\" {1}"), data.OriginalOutputPath / gradlew, distributionPackage ? TEXT("assemble") : TEXT("assembleDebug"));
|
||||||
procSettings.WorkingDirectory = data.OriginalOutputPath;
|
procSettings.WorkingDirectory = data.OriginalOutputPath;
|
||||||
@@ -292,6 +299,7 @@ bool AndroidPlatformTools::OnPostProcess(CookingData& data)
|
|||||||
data.Error(String::Format(TEXT("Failed to build Gradle project into package (result code: {0}). See log for more info."), result));
|
data.Error(String::Format(TEXT("Failed to build Gradle project into package (result code: {0}). See log for more info."), result));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Copy result package
|
// Copy result package
|
||||||
const String apk = data.OriginalOutputPath / (distributionPackage ? TEXT("app/build/outputs/apk/release/app-release-unsigned.apk") : TEXT("app/build/outputs/apk/debug/app-debug.apk"));
|
const String apk = data.OriginalOutputPath / (distributionPackage ? TEXT("app/build/outputs/apk/release/app-release-unsigned.apk") : TEXT("app/build/outputs/apk/debug/app-debug.apk"));
|
||||||
|
|||||||
@@ -104,4 +104,19 @@ bool LinuxPlatformTools::OnDeployBinaries(CookingData& data)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LinuxPlatformTools::OnRun(CookingData& data, String& executableFile, String& commandLineFormat, String& workingDir)
|
||||||
|
{
|
||||||
|
// Pick the first executable file
|
||||||
|
Array<String> files;
|
||||||
|
FileSystem::DirectoryGetFiles(files, data.NativeCodeOutputPath, TEXT("*"), DirectorySearchOption::TopDirectoryOnly);
|
||||||
|
for (auto& file : files)
|
||||||
|
{
|
||||||
|
if (FileSystem::GetExtension(file).IsEmpty())
|
||||||
|
{
|
||||||
|
executableFile = file;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ public:
|
|||||||
ArchitectureType GetArchitecture() const override;
|
ArchitectureType GetArchitecture() const override;
|
||||||
bool UseSystemDotnet() const override;
|
bool UseSystemDotnet() const override;
|
||||||
bool OnDeployBinaries(CookingData& data) override;
|
bool OnDeployBinaries(CookingData& data) override;
|
||||||
|
void OnRun(CookingData& data, String& executableFile, String& commandLineFormat, String& workingDir) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -249,4 +249,19 @@ bool MacPlatformTools::OnPostProcess(CookingData& data)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MacPlatformTools::OnRun(CookingData& data, String& executableFile, String& commandLineFormat, String& workingDir)
|
||||||
|
{
|
||||||
|
// Pick the first executable file
|
||||||
|
Array<String> files;
|
||||||
|
FileSystem::DirectoryGetFiles(files, data.NativeCodeOutputPath, TEXT("*"), DirectorySearchOption::TopDirectoryOnly);
|
||||||
|
for (auto& file : files)
|
||||||
|
{
|
||||||
|
if (FileSystem::GetExtension(file).IsEmpty())
|
||||||
|
{
|
||||||
|
executableFile = file;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ public:
|
|||||||
bool IsNativeCodeFile(CookingData& data, const String& file) override;
|
bool IsNativeCodeFile(CookingData& data, const String& file) override;
|
||||||
void OnBuildStarted(CookingData& data) override;
|
void OnBuildStarted(CookingData& data) override;
|
||||||
bool OnPostProcess(CookingData& data) override;
|
bool OnPostProcess(CookingData& data) override;
|
||||||
|
void OnRun(CookingData& data, String& executableFile, String& commandLineFormat, String& workingDir) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -188,8 +188,8 @@ bool CompileScriptsStep::Perform(CookingData& data)
|
|||||||
LOG(Info, "Starting scripts compilation for game...");
|
LOG(Info, "Starting scripts compilation for game...");
|
||||||
const String logFile = data.CacheDirectory / TEXT("CompileLog.txt");
|
const String logFile = data.CacheDirectory / TEXT("CompileLog.txt");
|
||||||
auto args = String::Format(
|
auto args = String::Format(
|
||||||
TEXT("-log -logfile=\"{4}\" -build -mutex -buildtargets={0} -platform={1} -arch={2} -configuration={3} -aotMode={5}"),
|
TEXT("-log -logfile=\"{4}\" -build -mutex -buildtargets={0} -platform={1} -arch={2} -configuration={3} -aotMode={5} {6}"),
|
||||||
target, platform, architecture, configuration, logFile, ToString(data.Tools->UseAOT()));
|
target, platform, architecture, configuration, logFile, ToString(data.Tools->UseAOT()), GAME_BUILD_DOTNET_VER);
|
||||||
#if PLATFORM_WINDOWS
|
#if PLATFORM_WINDOWS
|
||||||
if (data.Platform == BuildPlatform::LinuxX64)
|
if (data.Platform == BuildPlatform::LinuxX64)
|
||||||
#elif PLATFORM_LINUX
|
#elif PLATFORM_LINUX
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ bool DeployDataStep::Perform(CookingData& data)
|
|||||||
{
|
{
|
||||||
// Ask Flax.Build to provide .Net SDK location for the current platform
|
// Ask Flax.Build to provide .Net SDK location for the current platform
|
||||||
String sdks;
|
String sdks;
|
||||||
bool failed = ScriptsBuilder::RunBuildTool(TEXT("-log -logMessagesOnly -logFileWithConsole -logfile=SDKs.txt -printSDKs"), data.CacheDirectory);
|
bool failed = ScriptsBuilder::RunBuildTool(String::Format(TEXT("-log -logMessagesOnly -logFileWithConsole -logfile=SDKs.txt -printSDKs {}"), GAME_BUILD_DOTNET_VER), data.CacheDirectory);
|
||||||
failed |= File::ReadAllText(data.CacheDirectory / TEXT("SDKs.txt"), sdks);
|
failed |= File::ReadAllText(data.CacheDirectory / TEXT("SDKs.txt"), sdks);
|
||||||
int32 idx = sdks.Find(TEXT("DotNetSdk, "), StringSearchCase::CaseSensitive);
|
int32 idx = sdks.Find(TEXT("DotNetSdk, "), StringSearchCase::CaseSensitive);
|
||||||
if (idx != -1)
|
if (idx != -1)
|
||||||
@@ -168,7 +168,7 @@ bool DeployDataStep::Perform(CookingData& data)
|
|||||||
String sdks;
|
String sdks;
|
||||||
const Char *platformName, *archName;
|
const Char *platformName, *archName;
|
||||||
data.GetBuildPlatformName(platformName, archName);
|
data.GetBuildPlatformName(platformName, archName);
|
||||||
String args = String::Format(TEXT("-log -logMessagesOnly -logFileWithConsole -logfile=SDKs.txt -printDotNetRuntime -platform={} -arch={}"), platformName, archName);
|
String args = String::Format(TEXT("-log -logMessagesOnly -logFileWithConsole -logfile=SDKs.txt -printDotNetRuntime -platform={} -arch={} {}"), platformName, archName, GAME_BUILD_DOTNET_VER);
|
||||||
bool failed = ScriptsBuilder::RunBuildTool(args, data.CacheDirectory);
|
bool failed = ScriptsBuilder::RunBuildTool(args, data.CacheDirectory);
|
||||||
failed |= File::ReadAllText(data.CacheDirectory / TEXT("SDKs.txt"), sdks);
|
failed |= File::ReadAllText(data.CacheDirectory / TEXT("SDKs.txt"), sdks);
|
||||||
Array<String> parts;
|
Array<String> parts;
|
||||||
@@ -269,8 +269,8 @@ bool DeployDataStep::Perform(CookingData& data)
|
|||||||
LOG(Info, "Optimizing .NET class library size to include only used assemblies");
|
LOG(Info, "Optimizing .NET class library size to include only used assemblies");
|
||||||
const String logFile = data.CacheDirectory / TEXT("StripDotnetLibs.txt");
|
const String logFile = data.CacheDirectory / TEXT("StripDotnetLibs.txt");
|
||||||
String args = String::Format(
|
String args = String::Format(
|
||||||
TEXT("-log -logfile=\"{}\" -runDotNetClassLibStripping -mutex -binaries=\"{}\""),
|
TEXT("-log -logfile=\"{}\" -runDotNetClassLibStripping -mutex -binaries=\"{}\" {}"),
|
||||||
logFile, data.DataOutputPath);
|
logFile, data.DataOutputPath, GAME_BUILD_DOTNET_VER);
|
||||||
for (const String& define : data.CustomDefines)
|
for (const String& define : data.CustomDefines)
|
||||||
{
|
{
|
||||||
args += TEXT(" -D");
|
args += TEXT(" -D");
|
||||||
|
|||||||
@@ -67,8 +67,8 @@ bool PrecompileAssembliesStep::Perform(CookingData& data)
|
|||||||
data.GetBuildPlatformName(platform, architecture);
|
data.GetBuildPlatformName(platform, architecture);
|
||||||
const String logFile = data.CacheDirectory / TEXT("AOTLog.txt");
|
const String logFile = data.CacheDirectory / TEXT("AOTLog.txt");
|
||||||
String args = String::Format(
|
String args = String::Format(
|
||||||
TEXT("-log -logfile=\"{}\" -runDotNetAOT -mutex -platform={} -arch={} -configuration={} -aotMode={} -binaries=\"{}\" -intermediate=\"{}\""),
|
TEXT("-log -logfile=\"{}\" -runDotNetAOT -mutex -platform={} -arch={} -configuration={} -aotMode={} -binaries=\"{}\" -intermediate=\"{}\" {}"),
|
||||||
logFile, platform, architecture, configuration, ToString(aotMode), data.DataOutputPath, data.ManagedCodeOutputPath);
|
logFile, platform, architecture, configuration, ToString(aotMode), data.DataOutputPath, data.ManagedCodeOutputPath, GAME_BUILD_DOTNET_VER);
|
||||||
if (!buildSettings.SkipUnusedDotnetLibsPackaging)
|
if (!buildSettings.SkipUnusedDotnetLibsPackaging)
|
||||||
args += TEXT(" -skipUnusedDotnetLibs=false"); // Run AOT on whole class library (not just used libs)
|
args += TEXT(" -skipUnusedDotnetLibs=false"); // Run AOT on whole class library (not just used libs)
|
||||||
for (const String& define : data.CustomDefines)
|
for (const String& define : data.CustomDefines)
|
||||||
|
|||||||
@@ -157,6 +157,12 @@ namespace FlaxEditor.CustomEditors
|
|||||||
var values = _values;
|
var values = _values;
|
||||||
var presenter = _presenter;
|
var presenter = _presenter;
|
||||||
var layout = _layout;
|
var layout = _layout;
|
||||||
|
if (layout.Editors.Count > 1)
|
||||||
|
{
|
||||||
|
// There are more editors using the same layout so rebuild parent editor to prevent removing others editors
|
||||||
|
_parent?.RebuildLayout();
|
||||||
|
return;
|
||||||
|
}
|
||||||
var control = layout.ContainerControl;
|
var control = layout.ContainerControl;
|
||||||
var parent = _parent;
|
var parent = _parent;
|
||||||
var parentScrollV = (_presenter?.Panel.Parent as Panel)?.VScrollBar?.Value ?? -1;
|
var parentScrollV = (_presenter?.Panel.Parent as Panel)?.VScrollBar?.Value ?? -1;
|
||||||
|
|||||||
@@ -225,8 +225,15 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
}
|
}
|
||||||
_actor = actor;
|
_actor = actor;
|
||||||
|
|
||||||
var showActorPicker = actor == null || ParentEditor.Values.All(x => x is not Cloth);
|
if (ParentEditor.Values.Any(x => x is Cloth))
|
||||||
if (showActorPicker)
|
{
|
||||||
|
// Cloth always picks the parent model mesh
|
||||||
|
if (actor == null)
|
||||||
|
{
|
||||||
|
layout.Label("Cloth needs to be added as a child to model actor.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
// Actor reference picker
|
// Actor reference picker
|
||||||
_actorPicker = layout.Custom<FlaxObjectRefPickerControl>();
|
_actorPicker = layout.Custom<FlaxObjectRefPickerControl>();
|
||||||
@@ -242,7 +249,10 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
{
|
{
|
||||||
var model = staticModel.Model;
|
var model = staticModel.Model;
|
||||||
if (model == null || model.WaitForLoaded())
|
if (model == null || model.WaitForLoaded())
|
||||||
|
{
|
||||||
|
layout.Label("No model.");
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
var materials = model.MaterialSlots;
|
var materials = model.MaterialSlots;
|
||||||
var lods = model.LODs;
|
var lods = model.LODs;
|
||||||
meshNames = new string[lods.Length][];
|
meshNames = new string[lods.Length][];
|
||||||
@@ -267,7 +277,10 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
{
|
{
|
||||||
var skinnedModel = animatedModel.SkinnedModel;
|
var skinnedModel = animatedModel.SkinnedModel;
|
||||||
if (skinnedModel == null || skinnedModel.WaitForLoaded())
|
if (skinnedModel == null || skinnedModel.WaitForLoaded())
|
||||||
|
{
|
||||||
|
layout.Label("No model.");
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
var materials = skinnedModel.MaterialSlots;
|
var materials = skinnedModel.MaterialSlots;
|
||||||
var lods = skinnedModel.LODs;
|
var lods = skinnedModel.LODs;
|
||||||
meshNames = new string[lods.Length][];
|
meshNames = new string[lods.Length][];
|
||||||
|
|||||||
@@ -37,41 +37,32 @@ public class MissingScriptEditor : GenericEditor
|
|||||||
Parent = _dropPanel,
|
Parent = _dropPanel,
|
||||||
Height = 64,
|
Height = 64,
|
||||||
};
|
};
|
||||||
|
|
||||||
_replaceScriptButton = new Button
|
_replaceScriptButton = new Button
|
||||||
{
|
{
|
||||||
Text = "Replace Script",
|
Text = "Replace Script",
|
||||||
TooltipText = "Replaces the missing script with a given script type",
|
TooltipText = "Replaces the missing script with a given script type",
|
||||||
AnchorPreset = AnchorPresets.TopCenter,
|
AnchorPreset = AnchorPresets.TopCenter,
|
||||||
Width = 240,
|
Bounds = new Rectangle(-120, 0, 240, 24),
|
||||||
Height = 24,
|
|
||||||
X = -120,
|
|
||||||
Y = 0,
|
|
||||||
Parent = replaceScriptPanel,
|
Parent = replaceScriptPanel,
|
||||||
};
|
};
|
||||||
_replaceScriptButton.Clicked += OnReplaceScriptButtonClicked;
|
_replaceScriptButton.Clicked += OnReplaceScriptButtonClicked;
|
||||||
|
|
||||||
var replaceAllLabel = new Label
|
var replaceAllLabel = new Label
|
||||||
{
|
{
|
||||||
Text = "Replace all matching missing scripts",
|
Text = "Replace all matching missing scripts",
|
||||||
TooltipText = "Whether or not to apply this script change to all scripts missing the same type.",
|
TooltipText = "Whether or not to apply this script change to all scripts missing the same type.",
|
||||||
AnchorPreset = AnchorPresets.BottomCenter,
|
AnchorPreset = AnchorPresets.BottomCenter,
|
||||||
Y = -34,
|
Y = -38,
|
||||||
Parent = replaceScriptPanel,
|
Parent = replaceScriptPanel,
|
||||||
};
|
};
|
||||||
replaceAllLabel.X -= FlaxEngine.GUI.Style.Current.FontSmall.MeasureText(replaceAllLabel.Text).X;
|
|
||||||
|
|
||||||
_shouldReplaceAllCheckbox = new CheckBox
|
_shouldReplaceAllCheckbox = new CheckBox
|
||||||
{
|
{
|
||||||
TooltipText = replaceAllLabel.TooltipText,
|
TooltipText = replaceAllLabel.TooltipText,
|
||||||
AnchorPreset = AnchorPresets.BottomCenter,
|
AnchorPreset = AnchorPresets.BottomCenter,
|
||||||
Y = -34,
|
Y = -38,
|
||||||
Parent = replaceScriptPanel,
|
Parent = replaceScriptPanel,
|
||||||
};
|
};
|
||||||
|
_shouldReplaceAllCheckbox.X -= _replaceScriptButton.Width * 0.5f + 0.5f;
|
||||||
float centerDifference = (_shouldReplaceAllCheckbox.Right - replaceAllLabel.Left) / 2;
|
replaceAllLabel.X -= 52;
|
||||||
replaceAllLabel.X += centerDifference;
|
|
||||||
_shouldReplaceAllCheckbox.X += centerDifference;
|
|
||||||
|
|
||||||
base.Initialize(layout);
|
base.Initialize(layout);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -695,7 +695,41 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
private void SetType(ref ScriptType controlType, UIControl uiControl)
|
private void SetType(ref ScriptType controlType, UIControl uiControl)
|
||||||
{
|
{
|
||||||
string previousName = uiControl.Control?.GetType().Name ?? nameof(UIControl);
|
string previousName = uiControl.Control?.GetType().Name ?? nameof(UIControl);
|
||||||
uiControl.Control = (Control)controlType.CreateInstance();
|
|
||||||
|
var oldControlType = (Control)uiControl.Control;
|
||||||
|
var newControlType = (Control)controlType.CreateInstance();
|
||||||
|
|
||||||
|
// copy old control data to new control
|
||||||
|
if (oldControlType != null)
|
||||||
|
{
|
||||||
|
newControlType.Visible = oldControlType.Visible;
|
||||||
|
newControlType.Enabled = oldControlType.Enabled;
|
||||||
|
newControlType.AutoFocus = oldControlType.AutoFocus;
|
||||||
|
|
||||||
|
newControlType.AnchorMin = oldControlType.AnchorMin;
|
||||||
|
newControlType.AnchorMax = oldControlType.AnchorMax;
|
||||||
|
newControlType.Offsets = oldControlType.Offsets;
|
||||||
|
|
||||||
|
newControlType.LocalLocation = oldControlType.LocalLocation;
|
||||||
|
newControlType.Scale = oldControlType.Scale;
|
||||||
|
newControlType.Bounds = oldControlType.Bounds;
|
||||||
|
newControlType.Width = oldControlType.Width;
|
||||||
|
newControlType.Height = oldControlType.Height;
|
||||||
|
newControlType.Center = oldControlType.Center;
|
||||||
|
newControlType.PivotRelative = oldControlType.PivotRelative;
|
||||||
|
|
||||||
|
newControlType.Pivot = oldControlType.Pivot;
|
||||||
|
newControlType.Shear = oldControlType.Shear;
|
||||||
|
newControlType.Rotation = oldControlType.Rotation;
|
||||||
|
}
|
||||||
|
if (oldControlType is ContainerControl oldContainer && newControlType is ContainerControl newContainer)
|
||||||
|
{
|
||||||
|
newContainer.CullChildren = oldContainer.CullChildren;
|
||||||
|
newContainer.ClipChildren = oldContainer.ClipChildren;
|
||||||
|
}
|
||||||
|
|
||||||
|
uiControl.Control = newControlType;
|
||||||
|
|
||||||
if (uiControl.Name.StartsWith(previousName))
|
if (uiControl.Name.StartsWith(previousName))
|
||||||
{
|
{
|
||||||
string newName = controlType.Name + uiControl.Name.Substring(previousName.Length);
|
string newName = controlType.Name + uiControl.Name.Substring(previousName.Length);
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
value = 0;
|
value = 0;
|
||||||
|
|
||||||
// If selected is single actor that has children, ask if apply layer to the sub objects as well
|
// If selected is single actor that has children, ask if apply layer to the sub objects as well
|
||||||
if (Values.IsSingleObject && (int)Values[0] != value && ParentEditor.Values[0] is Actor actor && actor.HasChildren)
|
if (Values.IsSingleObject && (int)Values[0] != value && ParentEditor.Values[0] is Actor actor && actor.HasChildren && !Editor.IsPlayMode)
|
||||||
{
|
{
|
||||||
var valueText = comboBox.SelectedItem;
|
var valueText = comboBox.SelectedItem;
|
||||||
|
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
{
|
{
|
||||||
// Generic file picker
|
// Generic file picker
|
||||||
assetType = ScriptType.Null;
|
assetType = ScriptType.Null;
|
||||||
Picker.FileExtension = assetReference.TypeName;
|
Picker.Validator.FileExtension = assetReference.TypeName;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -85,7 +85,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Picker.AssetType = assetType;
|
Picker.Validator.AssetType = assetType;
|
||||||
Picker.Height = height;
|
Picker.Height = height;
|
||||||
Picker.SelectedItemChanged += OnSelectedItemChanged;
|
Picker.SelectedItemChanged += OnSelectedItemChanged;
|
||||||
}
|
}
|
||||||
@@ -95,15 +95,15 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
if (_isRefreshing)
|
if (_isRefreshing)
|
||||||
return;
|
return;
|
||||||
if (typeof(AssetItem).IsAssignableFrom(_valueType.Type))
|
if (typeof(AssetItem).IsAssignableFrom(_valueType.Type))
|
||||||
SetValue(Picker.SelectedItem);
|
SetValue(Picker.Validator.SelectedItem);
|
||||||
else if (_valueType.Type == typeof(Guid))
|
else if (_valueType.Type == typeof(Guid))
|
||||||
SetValue(Picker.SelectedID);
|
SetValue(Picker.Validator.SelectedID);
|
||||||
else if (_valueType.Type == typeof(SceneReference))
|
else if (_valueType.Type == typeof(SceneReference))
|
||||||
SetValue(new SceneReference(Picker.SelectedID));
|
SetValue(new SceneReference(Picker.Validator.SelectedID));
|
||||||
else if (_valueType.Type == typeof(string))
|
else if (_valueType.Type == typeof(string))
|
||||||
SetValue(Picker.SelectedPath);
|
SetValue(Picker.Validator.SelectedPath);
|
||||||
else
|
else
|
||||||
SetValue(Picker.SelectedAsset);
|
SetValue(Picker.Validator.SelectedAsset);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@@ -115,15 +115,15 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
{
|
{
|
||||||
_isRefreshing = true;
|
_isRefreshing = true;
|
||||||
if (Values[0] is AssetItem assetItem)
|
if (Values[0] is AssetItem assetItem)
|
||||||
Picker.SelectedItem = assetItem;
|
Picker.Validator.SelectedItem = assetItem;
|
||||||
else if (Values[0] is Guid guid)
|
else if (Values[0] is Guid guid)
|
||||||
Picker.SelectedID = guid;
|
Picker.Validator.SelectedID = guid;
|
||||||
else if (Values[0] is SceneReference sceneAsset)
|
else if (Values[0] is SceneReference sceneAsset)
|
||||||
Picker.SelectedItem = Editor.Instance.ContentDatabase.FindAsset(sceneAsset.ID);
|
Picker.Validator.SelectedItem = Editor.Instance.ContentDatabase.FindAsset(sceneAsset.ID);
|
||||||
else if (Values[0] is string path)
|
else if (Values[0] is string path)
|
||||||
Picker.SelectedPath = path;
|
Picker.Validator.SelectedPath = path;
|
||||||
else
|
else
|
||||||
Picker.SelectedAsset = Values[0] as Asset;
|
Picker.Validator.SelectedAsset = Values[0] as Asset;
|
||||||
_isRefreshing = false;
|
_isRefreshing = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -171,11 +171,13 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
tree.Select(typeNode);
|
tree.Select(typeNode);
|
||||||
if (addItems)
|
if (addItems)
|
||||||
{
|
{
|
||||||
var items = GenericEditor.GetItemsForType(type, type.IsClass, true);
|
var items = GenericEditor.GetItemsForType(type, type.IsClass, true, true);
|
||||||
foreach (var item in items)
|
foreach (var item in items)
|
||||||
{
|
{
|
||||||
if (typed && !typed.IsAssignableFrom(item.Info.ValueType))
|
if (typed && !typed.IsAssignableFrom(item.Info.ValueType))
|
||||||
continue;
|
continue;
|
||||||
|
if (item.Info.DeclaringType.Type == typeof(FlaxEngine.Object))
|
||||||
|
continue; // Skip engine internals
|
||||||
var itemPath = typePath + item.Info.Name;
|
var itemPath = typePath + item.Info.Name;
|
||||||
var node = new TreeNode
|
var node = new TreeNode
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3,9 +3,12 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using FlaxEditor.Content;
|
||||||
using FlaxEditor.CustomEditors.Elements;
|
using FlaxEditor.CustomEditors.Elements;
|
||||||
using FlaxEditor.CustomEditors.GUI;
|
using FlaxEditor.CustomEditors.GUI;
|
||||||
using FlaxEditor.GUI.ContextMenu;
|
using FlaxEditor.GUI.ContextMenu;
|
||||||
|
using FlaxEditor.GUI.Drag;
|
||||||
|
using FlaxEditor.SceneGraph;
|
||||||
using FlaxEditor.Scripting;
|
using FlaxEditor.Scripting;
|
||||||
using FlaxEngine;
|
using FlaxEngine;
|
||||||
using FlaxEngine.GUI;
|
using FlaxEngine.GUI;
|
||||||
@@ -110,7 +113,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
public override void Initialize(LayoutElementsContainer layout)
|
public override void Initialize(LayoutElementsContainer layout)
|
||||||
{
|
{
|
||||||
// No support for different collections for now
|
// No support for different collections for now
|
||||||
if (HasDifferentValues || HasDifferentTypes)
|
if (HasDifferentTypes)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var size = Count;
|
var size = Count;
|
||||||
@@ -135,14 +138,43 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
spacing = collection.Spacing;
|
spacing = collection.Spacing;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Size
|
var dragArea = layout.CustomContainer<DragAreaControl>();
|
||||||
if (_readOnly || (NotNullItems && size == 0))
|
dragArea.CustomControl.Editor = this;
|
||||||
|
dragArea.CustomControl.ElementType = ElementType;
|
||||||
|
|
||||||
|
// Check for the AssetReferenceAttribute. In JSON assets, it can be used to filter
|
||||||
|
// which scripts can be dragged over and dropped on this collection editor.
|
||||||
|
var assetReference = (AssetReferenceAttribute)attributes?.FirstOrDefault(x => x is AssetReferenceAttribute);
|
||||||
|
if (assetReference != null)
|
||||||
{
|
{
|
||||||
layout.Label("Size", size.ToString());
|
if (string.IsNullOrEmpty(assetReference.TypeName))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else if (assetReference.TypeName.Length > 1 && assetReference.TypeName[0] == '.')
|
||||||
|
{
|
||||||
|
dragArea.CustomControl.ElementType = ScriptType.Null;
|
||||||
|
dragArea.CustomControl.FileExtension = assetReference.TypeName;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_size = layout.IntegerValue("Size");
|
var customType = TypeUtils.GetType(assetReference.TypeName);
|
||||||
|
if (customType != ScriptType.Null)
|
||||||
|
dragArea.CustomControl.ElementType = customType;
|
||||||
|
else if (!Content.Settings.GameSettings.OptionalPlatformSettings.Contains(assetReference.TypeName))
|
||||||
|
Debug.LogWarning(string.Format("Unknown asset type '{0}' to use for drag and drop filter.", assetReference.TypeName));
|
||||||
|
else
|
||||||
|
dragArea.CustomControl.ElementType = ScriptType.Void;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Size
|
||||||
|
if (_readOnly || (NotNullItems && size == 0))
|
||||||
|
{
|
||||||
|
dragArea.Label("Size", size.ToString());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_size = dragArea.IntegerValue("Size");
|
||||||
_size.IntValue.MinValue = 0;
|
_size.IntValue.MinValue = 0;
|
||||||
_size.IntValue.MaxValue = ushort.MaxValue;
|
_size.IntValue.MaxValue = ushort.MaxValue;
|
||||||
_size.IntValue.Value = size;
|
_size.IntValue.Value = size;
|
||||||
@@ -152,7 +184,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
// Elements
|
// Elements
|
||||||
if (size > 0)
|
if (size > 0)
|
||||||
{
|
{
|
||||||
var panel = layout.VerticalPanel();
|
var panel = dragArea.VerticalPanel();
|
||||||
panel.Panel.BackgroundColor = _background;
|
panel.Panel.BackgroundColor = _background;
|
||||||
var elementType = ElementType;
|
var elementType = ElementType;
|
||||||
|
|
||||||
@@ -212,37 +244,33 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
// Add/Remove buttons
|
// Add/Remove buttons
|
||||||
if (!_readOnly)
|
if (!_readOnly)
|
||||||
{
|
{
|
||||||
var area = layout.Space(20);
|
var panel = dragArea.HorizontalPanel();
|
||||||
var addButton = new Button(area.ContainerControl.Width - (16 + 16 + 2 + 2), 2, 16, 16)
|
panel.Panel.Size = new Float2(0, 20);
|
||||||
{
|
panel.Panel.Margin = new Margin(2);
|
||||||
Text = "+",
|
|
||||||
TooltipText = "Add new item",
|
|
||||||
AnchorPreset = AnchorPresets.TopRight,
|
|
||||||
Parent = area.ContainerControl,
|
|
||||||
Enabled = !NotNullItems || size > 0,
|
|
||||||
};
|
|
||||||
addButton.Clicked += () =>
|
|
||||||
{
|
|
||||||
if (IsSetBlocked)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Resize(Count + 1);
|
var removeButton = panel.Button("-", "Remove last item");
|
||||||
};
|
removeButton.Button.Size = new Float2(16, 16);
|
||||||
var removeButton = new Button(addButton.Right + 2, addButton.Y, 16, 16)
|
removeButton.Button.Enabled = size > 0;
|
||||||
{
|
removeButton.Button.AnchorPreset = AnchorPresets.TopRight;
|
||||||
Text = "-",
|
removeButton.Button.Clicked += () =>
|
||||||
TooltipText = "Remove last item",
|
|
||||||
AnchorPreset = AnchorPresets.TopRight,
|
|
||||||
Parent = area.ContainerControl,
|
|
||||||
Enabled = size > 0,
|
|
||||||
};
|
|
||||||
removeButton.Clicked += () =>
|
|
||||||
{
|
{
|
||||||
if (IsSetBlocked)
|
if (IsSetBlocked)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Resize(Count - 1);
|
Resize(Count - 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var addButton = panel.Button("+", "Add new item");
|
||||||
|
addButton.Button.Size = new Float2(16, 16);
|
||||||
|
addButton.Button.Enabled = !NotNullItems || size > 0;
|
||||||
|
addButton.Button.AnchorPreset = AnchorPresets.TopRight;
|
||||||
|
addButton.Button.Clicked += () =>
|
||||||
|
{
|
||||||
|
if (IsSetBlocked)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Resize(Count + 1);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -369,5 +397,232 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
}
|
}
|
||||||
return base.OnDirty(editor, value, token);
|
return base.OnDirty(editor, value, token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class DragAreaControl : VerticalPanel
|
||||||
|
{
|
||||||
|
private DragItems _dragItems;
|
||||||
|
private DragActors _dragActors;
|
||||||
|
private DragHandlers _dragHandlers;
|
||||||
|
private AssetPickerValidator _pickerValidator;
|
||||||
|
|
||||||
|
public ScriptType ElementType
|
||||||
|
{
|
||||||
|
get => _pickerValidator?.AssetType ?? ScriptType.Null;
|
||||||
|
set => _pickerValidator = new AssetPickerValidator(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CollectionEditor Editor { get; set; }
|
||||||
|
|
||||||
|
public string FileExtension
|
||||||
|
{
|
||||||
|
set => _pickerValidator.FileExtension = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void Draw()
|
||||||
|
{
|
||||||
|
if (_dragHandlers is { HasValidDrag: true })
|
||||||
|
{
|
||||||
|
var area = new Rectangle(Float2.Zero, Size);
|
||||||
|
Render2D.FillRectangle(area, Color.Orange * 0.5f);
|
||||||
|
Render2D.DrawRectangle(area, Color.Black);
|
||||||
|
}
|
||||||
|
|
||||||
|
base.Draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnDestroy()
|
||||||
|
{
|
||||||
|
_pickerValidator.OnDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool ValidateActors(ActorNode node)
|
||||||
|
{
|
||||||
|
return node.Actor.GetScript(ElementType.Type) || ElementType.Type.IsAssignableTo(typeof(Actor));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override DragDropEffect OnDragEnter(ref Float2 location, DragData data)
|
||||||
|
{
|
||||||
|
var result = base.OnDragEnter(ref location, data);
|
||||||
|
if (result != DragDropEffect.None)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
if (_dragHandlers == null)
|
||||||
|
{
|
||||||
|
_dragItems = new DragItems(_pickerValidator.IsValid);
|
||||||
|
_dragActors = new DragActors(ValidateActors);
|
||||||
|
_dragHandlers = new DragHandlers
|
||||||
|
{
|
||||||
|
_dragActors,
|
||||||
|
_dragItems
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return _dragHandlers.OnDragEnter(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override DragDropEffect OnDragMove(ref Float2 location, DragData data)
|
||||||
|
{
|
||||||
|
var result = base.OnDragMove(ref location, data);
|
||||||
|
if (result != DragDropEffect.None)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
return _dragHandlers.Effect;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnDragLeave()
|
||||||
|
{
|
||||||
|
_dragHandlers.OnDragLeave();
|
||||||
|
|
||||||
|
base.OnDragLeave();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override DragDropEffect OnDragDrop(ref Float2 location, DragData data)
|
||||||
|
{
|
||||||
|
var result = base.OnDragDrop(ref location, data);
|
||||||
|
if (result != DragDropEffect.None)
|
||||||
|
{
|
||||||
|
_dragHandlers.OnDragDrop(null);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_dragHandlers.HasValidDrag)
|
||||||
|
{
|
||||||
|
if (_dragItems.HasValidDrag)
|
||||||
|
{
|
||||||
|
var list = Editor.CloneValues();
|
||||||
|
if (list == null)
|
||||||
|
{
|
||||||
|
if (Editor.Values.Type.IsArray)
|
||||||
|
{
|
||||||
|
list = TypeUtils.CreateArrayInstance(Editor.Values.Type.GetElementType(), 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
list = Editor.Values.Type.CreateInstance() as IList;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (list.IsFixedSize)
|
||||||
|
{
|
||||||
|
var oldSize = list.Count;
|
||||||
|
var newSize = list.Count + _dragItems.Objects.Count;
|
||||||
|
var type = Editor.Values.Type.GetElementType();
|
||||||
|
var array = TypeUtils.CreateArrayInstance(type, newSize);
|
||||||
|
list.CopyTo(array, 0);
|
||||||
|
|
||||||
|
for (var i = oldSize; i < newSize; i++)
|
||||||
|
{
|
||||||
|
var validator = new AssetPickerValidator
|
||||||
|
{
|
||||||
|
FileExtension = _pickerValidator.FileExtension,
|
||||||
|
AssetType = _pickerValidator.AssetType,
|
||||||
|
SelectedItem = _dragItems.Objects[i - oldSize],
|
||||||
|
};
|
||||||
|
|
||||||
|
if (typeof(AssetItem).IsAssignableFrom(ElementType.Type))
|
||||||
|
array.SetValue(validator.SelectedItem, i);
|
||||||
|
else if (ElementType.Type == typeof(Guid))
|
||||||
|
array.SetValue(validator.SelectedID, i);
|
||||||
|
else if (ElementType.Type == typeof(SceneReference))
|
||||||
|
array.SetValue(new SceneReference(validator.SelectedID), i);
|
||||||
|
else if (ElementType.Type == typeof(string))
|
||||||
|
array.SetValue(validator.SelectedPath, i);
|
||||||
|
else
|
||||||
|
array.SetValue(validator.SelectedAsset, i);
|
||||||
|
|
||||||
|
validator.OnDestroy();
|
||||||
|
}
|
||||||
|
Editor.SetValue(array);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach (var item in _dragItems.Objects)
|
||||||
|
{
|
||||||
|
var validator = new AssetPickerValidator
|
||||||
|
{
|
||||||
|
FileExtension = _pickerValidator.FileExtension,
|
||||||
|
AssetType = _pickerValidator.AssetType,
|
||||||
|
SelectedItem = item,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (typeof(AssetItem).IsAssignableFrom(ElementType.Type))
|
||||||
|
list.Add(validator.SelectedItem);
|
||||||
|
else if (ElementType.Type == typeof(Guid))
|
||||||
|
list.Add(validator.SelectedID);
|
||||||
|
else if (ElementType.Type == typeof(SceneReference))
|
||||||
|
list.Add(new SceneReference(validator.SelectedID));
|
||||||
|
else if (ElementType.Type == typeof(string))
|
||||||
|
list.Add(validator.SelectedPath);
|
||||||
|
else
|
||||||
|
list.Add(validator.SelectedAsset);
|
||||||
|
|
||||||
|
validator.OnDestroy();
|
||||||
|
}
|
||||||
|
Editor.SetValue(list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (_dragActors.HasValidDrag)
|
||||||
|
{
|
||||||
|
var list = Editor.CloneValues();
|
||||||
|
if (list == null)
|
||||||
|
{
|
||||||
|
if (Editor.Values.Type.IsArray)
|
||||||
|
{
|
||||||
|
list = TypeUtils.CreateArrayInstance(Editor.Values.Type.GetElementType(), 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
list = Editor.Values.Type.CreateInstance() as IList;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (list.IsFixedSize)
|
||||||
|
{
|
||||||
|
var oldSize = list.Count;
|
||||||
|
var newSize = list.Count + _dragActors.Objects.Count;
|
||||||
|
var type = Editor.Values.Type.GetElementType();
|
||||||
|
var array = TypeUtils.CreateArrayInstance(type, newSize);
|
||||||
|
list.CopyTo(array, 0);
|
||||||
|
|
||||||
|
for (var i = oldSize; i < newSize; i++)
|
||||||
|
{
|
||||||
|
var actor = _dragActors.Objects[i - oldSize].Actor;
|
||||||
|
if (ElementType.Type.IsAssignableTo(typeof(Actor)))
|
||||||
|
{
|
||||||
|
array.SetValue(actor, i);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
array.SetValue(actor.GetScript(ElementType.Type), i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Editor.SetValue(array);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach (var actorNode in _dragActors.Objects)
|
||||||
|
{
|
||||||
|
if (ElementType.Type.IsAssignableTo(typeof(Actor)))
|
||||||
|
{
|
||||||
|
list.Add(actorNode.Actor);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
list.Add(actorNode.Actor.GetScript(ElementType.Type));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Editor.SetValue(list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_dragHandlers.OnDragDrop(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -247,8 +247,9 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
/// <param name="type">The type.</param>
|
/// <param name="type">The type.</param>
|
||||||
/// <param name="useProperties">True if use type properties.</param>
|
/// <param name="useProperties">True if use type properties.</param>
|
||||||
/// <param name="useFields">True if use type fields.</param>
|
/// <param name="useFields">True if use type fields.</param>
|
||||||
|
/// <param name="usePropertiesWithoutSetter">True if use type properties that have only getter method without setter method (aka read-only).</param>
|
||||||
/// <returns>The items.</returns>
|
/// <returns>The items.</returns>
|
||||||
public static List<ItemInfo> GetItemsForType(ScriptType type, bool useProperties, bool useFields)
|
public static List<ItemInfo> GetItemsForType(ScriptType type, bool useProperties, bool useFields, bool usePropertiesWithoutSetter = false)
|
||||||
{
|
{
|
||||||
var items = new List<ItemInfo>();
|
var items = new List<ItemInfo>();
|
||||||
|
|
||||||
@@ -264,7 +265,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
var showInEditor = attributes.Any(x => x is ShowInEditorAttribute);
|
var showInEditor = attributes.Any(x => x is ShowInEditorAttribute);
|
||||||
|
|
||||||
// Skip properties without getter or setter
|
// Skip properties without getter or setter
|
||||||
if (!p.HasGet || (!p.HasSet && !showInEditor))
|
if (!p.HasGet || (!p.HasSet && !showInEditor && !usePropertiesWithoutSetter))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Skip hidden fields, handle special attributes
|
// Skip hidden fields, handle special attributes
|
||||||
|
|||||||
@@ -28,14 +28,16 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
var group = layout.Group("Entry");
|
var group = layout.Group("Entry");
|
||||||
_group = group;
|
_group = group;
|
||||||
|
|
||||||
if (ParentEditor == null)
|
if (ParentEditor == null || HasDifferentTypes)
|
||||||
return;
|
return;
|
||||||
var entry = (ModelInstanceEntry)Values[0];
|
var entry = (ModelInstanceEntry)Values[0];
|
||||||
var entryIndex = ParentEditor.ChildrenEditors.IndexOf(this);
|
var entryIndex = ParentEditor.ChildrenEditors.IndexOf(this);
|
||||||
var materialLabel = new PropertyNameLabel("Material");
|
var materialLabel = new PropertyNameLabel("Material");
|
||||||
materialLabel.TooltipText = "The mesh surface material used for the rendering.";
|
materialLabel.TooltipText = "The mesh surface material used for the rendering.";
|
||||||
if (ParentEditor.ParentEditor?.Values[0] is ModelInstanceActor modelInstance)
|
var parentEditorValues = ParentEditor.ParentEditor?.Values;
|
||||||
|
if (parentEditorValues?[0] is ModelInstanceActor modelInstance)
|
||||||
{
|
{
|
||||||
|
// TODO: store _modelInstance and _material in array for each selected model instance actor
|
||||||
_entryIndex = entryIndex;
|
_entryIndex = entryIndex;
|
||||||
_modelInstance = modelInstance;
|
_modelInstance = modelInstance;
|
||||||
var slots = modelInstance.MaterialSlots;
|
var slots = modelInstance.MaterialSlots;
|
||||||
@@ -56,6 +58,8 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
|
|
||||||
// Create material picker
|
// Create material picker
|
||||||
var materialValue = new CustomValueContainer(new ScriptType(typeof(MaterialBase)), _material, (instance, index) => _material, (instance, index, value) => _material = value as MaterialBase);
|
var materialValue = new CustomValueContainer(new ScriptType(typeof(MaterialBase)), _material, (instance, index) => _material, (instance, index, value) => _material = value as MaterialBase);
|
||||||
|
for (var i = 1; i < parentEditorValues.Count; i++)
|
||||||
|
materialValue.Add(_material);
|
||||||
var materialEditor = (AssetRefEditor)_group.Property(materialLabel, materialValue);
|
var materialEditor = (AssetRefEditor)_group.Property(materialLabel, materialValue);
|
||||||
materialEditor.Values.SetDefaultValue(defaultValue);
|
materialEditor.Values.SetDefaultValue(defaultValue);
|
||||||
materialEditor.RefreshDefaultValue();
|
materialEditor.RefreshDefaultValue();
|
||||||
@@ -72,14 +76,14 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
return;
|
return;
|
||||||
_isRefreshing = true;
|
_isRefreshing = true;
|
||||||
var slots = _modelInstance.MaterialSlots;
|
var slots = _modelInstance.MaterialSlots;
|
||||||
var material = _materialEditor.Picker.SelectedAsset as MaterialBase;
|
var material = _materialEditor.Picker.Validator.SelectedAsset as MaterialBase;
|
||||||
var defaultMaterial = GPUDevice.Instance.DefaultMaterial;
|
var defaultMaterial = GPUDevice.Instance.DefaultMaterial;
|
||||||
var value = (ModelInstanceEntry)Values[0];
|
var value = (ModelInstanceEntry)Values[0];
|
||||||
var prevMaterial = value.Material;
|
var prevMaterial = value.Material;
|
||||||
if (!material)
|
if (!material)
|
||||||
{
|
{
|
||||||
// Fallback to default material
|
// Fallback to default material
|
||||||
_materialEditor.Picker.SelectedAsset = defaultMaterial;
|
_materialEditor.Picker.Validator.SelectedAsset = defaultMaterial;
|
||||||
value.Material = defaultMaterial;
|
value.Material = defaultMaterial;
|
||||||
}
|
}
|
||||||
else if (material == slots[_entryIndex].Material)
|
else if (material == slots[_entryIndex].Material)
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using System.IO;
|
|||||||
using FlaxEditor.Content;
|
using FlaxEditor.Content;
|
||||||
using FlaxEditor.GUI.Drag;
|
using FlaxEditor.GUI.Drag;
|
||||||
using FlaxEditor.Scripting;
|
using FlaxEditor.Scripting;
|
||||||
|
using FlaxEditor.Utilities;
|
||||||
using FlaxEngine;
|
using FlaxEngine;
|
||||||
using FlaxEngine.GUI;
|
using FlaxEngine.GUI;
|
||||||
using FlaxEngine.Utilities;
|
using FlaxEngine.Utilities;
|
||||||
@@ -17,189 +18,21 @@ namespace FlaxEditor.GUI
|
|||||||
/// <seealso cref="Control" />
|
/// <seealso cref="Control" />
|
||||||
/// <seealso cref="IContentItemOwner" />
|
/// <seealso cref="IContentItemOwner" />
|
||||||
[HideInEditor]
|
[HideInEditor]
|
||||||
public class AssetPicker : Control, IContentItemOwner
|
public class AssetPicker : Control
|
||||||
{
|
{
|
||||||
private const float DefaultIconSize = 64;
|
private const float DefaultIconSize = 64;
|
||||||
private const float ButtonsOffset = 2;
|
private const float ButtonsOffset = 2;
|
||||||
private const float ButtonsSize = 12;
|
private const float ButtonsSize = 12;
|
||||||
|
|
||||||
private Asset _selected;
|
|
||||||
private ContentItem _selectedItem;
|
|
||||||
private ScriptType _type;
|
|
||||||
private string _fileExtension;
|
|
||||||
|
|
||||||
private bool _isMouseDown;
|
private bool _isMouseDown;
|
||||||
private Float2 _mouseDownPos;
|
private Float2 _mouseDownPos;
|
||||||
private Float2 _mousePos;
|
private Float2 _mousePos;
|
||||||
private DragItems _dragOverElement;
|
private DragItems _dragOverElement;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the selected item.
|
/// The asset validator. Used to ensure only appropriate items can be picked.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ContentItem SelectedItem
|
public AssetPickerValidator Validator { get; }
|
||||||
{
|
|
||||||
get => _selectedItem;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (_selectedItem == value)
|
|
||||||
return;
|
|
||||||
if (value == null)
|
|
||||||
{
|
|
||||||
if (_selected == null && _selectedItem is SceneItem)
|
|
||||||
{
|
|
||||||
// Deselect scene reference
|
|
||||||
_selectedItem.RemoveReference(this);
|
|
||||||
_selectedItem = null;
|
|
||||||
_selected = null;
|
|
||||||
OnSelectedItemChanged();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deselect
|
|
||||||
_selectedItem?.RemoveReference(this);
|
|
||||||
_selectedItem = null;
|
|
||||||
_selected = null;
|
|
||||||
OnSelectedItemChanged();
|
|
||||||
}
|
|
||||||
else if (value is SceneItem item)
|
|
||||||
{
|
|
||||||
if (_selectedItem == item)
|
|
||||||
return;
|
|
||||||
if (!IsValid(item))
|
|
||||||
item = null;
|
|
||||||
|
|
||||||
// Change value to scene reference (cannot load asset because scene can be already loaded - duplicated ID issue)
|
|
||||||
_selectedItem?.RemoveReference(this);
|
|
||||||
_selectedItem = item;
|
|
||||||
_selected = null;
|
|
||||||
_selectedItem?.AddReference(this);
|
|
||||||
OnSelectedItemChanged();
|
|
||||||
}
|
|
||||||
else if (value is AssetItem assetItem)
|
|
||||||
{
|
|
||||||
SelectedAsset = FlaxEngine.Content.LoadAsync(assetItem.ID);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Change value
|
|
||||||
_selectedItem?.RemoveReference(this);
|
|
||||||
_selectedItem = value;
|
|
||||||
_selected = null;
|
|
||||||
OnSelectedItemChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the selected asset identifier.
|
|
||||||
/// </summary>
|
|
||||||
public Guid SelectedID
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_selected != null)
|
|
||||||
return _selected.ID;
|
|
||||||
if (_selectedItem is AssetItem assetItem)
|
|
||||||
return assetItem.ID;
|
|
||||||
return Guid.Empty;
|
|
||||||
}
|
|
||||||
set => SelectedItem = Editor.Instance.ContentDatabase.FindAsset(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the selected content item path.
|
|
||||||
/// </summary>
|
|
||||||
public string SelectedPath
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
string path = _selectedItem?.Path ?? _selected?.Path;
|
|
||||||
if (path != null)
|
|
||||||
{
|
|
||||||
// Convert into path relative to the project (cross-platform)
|
|
||||||
var projectFolder = Globals.ProjectFolder;
|
|
||||||
if (path.StartsWith(projectFolder))
|
|
||||||
path = path.Substring(projectFolder.Length + 1);
|
|
||||||
}
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(value))
|
|
||||||
{
|
|
||||||
SelectedItem = null;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var path = StringUtils.IsRelative(value) ? Path.Combine(Globals.ProjectFolder, value) : value;
|
|
||||||
SelectedItem = Editor.Instance.ContentDatabase.Find(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the selected asset object.
|
|
||||||
/// </summary>
|
|
||||||
public Asset SelectedAsset
|
|
||||||
{
|
|
||||||
get => _selected;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
// Check if value won't change
|
|
||||||
if (value == _selected)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Find item from content database and check it
|
|
||||||
var item = value ? Editor.Instance.ContentDatabase.FindAsset(value.ID) : null;
|
|
||||||
if (item != null && !IsValid(item))
|
|
||||||
item = null;
|
|
||||||
|
|
||||||
// Change value
|
|
||||||
_selectedItem?.RemoveReference(this);
|
|
||||||
_selectedItem = item;
|
|
||||||
_selected = value;
|
|
||||||
_selectedItem?.AddReference(this);
|
|
||||||
OnSelectedItemChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the assets types that this picker accepts (it supports types derived from the given type). Use <see cref="ScriptType.Null"/> for generic file picker.
|
|
||||||
/// </summary>
|
|
||||||
public ScriptType AssetType
|
|
||||||
{
|
|
||||||
get => _type;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (_type != value)
|
|
||||||
{
|
|
||||||
_type = value;
|
|
||||||
|
|
||||||
// Auto deselect if the current value is invalid
|
|
||||||
if (_selectedItem != null && !IsValid(_selectedItem))
|
|
||||||
SelectedItem = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the content items extensions filter. Null if unused.
|
|
||||||
/// </summary>
|
|
||||||
public string FileExtension
|
|
||||||
{
|
|
||||||
get => _fileExtension;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (_fileExtension != value)
|
|
||||||
{
|
|
||||||
_fileExtension = value;
|
|
||||||
|
|
||||||
// Auto deselect if the current value is invalid
|
|
||||||
if (_selectedItem != null && !IsValid(_selectedItem))
|
|
||||||
SelectedItem = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Occurs when selected item gets changed.
|
/// Occurs when selected item gets changed.
|
||||||
@@ -216,38 +49,6 @@ namespace FlaxEditor.GUI
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool CanEdit = true;
|
public bool CanEdit = true;
|
||||||
|
|
||||||
private bool IsValid(ContentItem item)
|
|
||||||
{
|
|
||||||
if (_fileExtension != null && !item.Path.EndsWith(_fileExtension))
|
|
||||||
return false;
|
|
||||||
if (CheckValid != null && !CheckValid(item))
|
|
||||||
return false;
|
|
||||||
if (_type == ScriptType.Null)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (item is AssetItem assetItem)
|
|
||||||
{
|
|
||||||
// Faster path for binary items (in-built)
|
|
||||||
if (assetItem is BinaryAssetItem binaryItem)
|
|
||||||
return _type.IsAssignableFrom(new ScriptType(binaryItem.Type));
|
|
||||||
|
|
||||||
// Type filter
|
|
||||||
var type = TypeUtils.GetType(assetItem.TypeName);
|
|
||||||
if (_type.IsAssignableFrom(type))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// Json assets can contain any type of the object defined by the C# type (data oriented design)
|
|
||||||
if (assetItem is JsonAssetItem && (_type.Type == typeof(JsonAsset) || _type.Type == typeof(Asset)))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// Special case for scene asset references
|
|
||||||
if (_type.Type == typeof(SceneReference) && assetItem is SceneItem)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="AssetPicker"/> class.
|
/// Initializes a new instance of the <see cref="AssetPicker"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -264,7 +65,8 @@ namespace FlaxEditor.GUI
|
|||||||
public AssetPicker(ScriptType assetType, Float2 location)
|
public AssetPicker(ScriptType assetType, Float2 location)
|
||||||
: base(location, new Float2(DefaultIconSize + ButtonsOffset + ButtonsSize, DefaultIconSize))
|
: base(location, new Float2(DefaultIconSize + ButtonsOffset + ButtonsSize, DefaultIconSize))
|
||||||
{
|
{
|
||||||
_type = assetType;
|
Validator = new AssetPickerValidator(assetType);
|
||||||
|
Validator.SelectedItemChanged += OnSelectedItemChanged;
|
||||||
_mousePos = Float2.Minimum;
|
_mousePos = Float2.Minimum;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -275,10 +77,10 @@ namespace FlaxEditor.GUI
|
|||||||
{
|
{
|
||||||
// Update tooltip
|
// Update tooltip
|
||||||
string tooltip;
|
string tooltip;
|
||||||
if (_selectedItem is AssetItem assetItem)
|
if (Validator.SelectedItem is AssetItem assetItem)
|
||||||
tooltip = assetItem.NamePath;
|
tooltip = assetItem.NamePath;
|
||||||
else
|
else
|
||||||
tooltip = SelectedPath;
|
tooltip = Validator.SelectedPath;
|
||||||
TooltipText = tooltip;
|
TooltipText = tooltip;
|
||||||
|
|
||||||
SelectedItemChanged?.Invoke();
|
SelectedItemChanged?.Invoke();
|
||||||
@@ -289,37 +91,13 @@ namespace FlaxEditor.GUI
|
|||||||
// Do the drag drop operation if has selected element
|
// Do the drag drop operation if has selected element
|
||||||
if (new Rectangle(Float2.Zero, Size).Contains(ref _mouseDownPos))
|
if (new Rectangle(Float2.Zero, Size).Contains(ref _mouseDownPos))
|
||||||
{
|
{
|
||||||
if (_selected != null)
|
if (Validator.SelectedAsset != null)
|
||||||
DoDragDrop(DragAssets.GetDragData(_selected));
|
DoDragDrop(DragAssets.GetDragData(Validator.SelectedAsset));
|
||||||
else if (_selectedItem != null)
|
else if (Validator.SelectedItem != null)
|
||||||
DoDragDrop(DragItems.GetDragData(_selectedItem));
|
DoDragDrop(DragItems.GetDragData(Validator.SelectedItem));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public void OnItemDeleted(ContentItem item)
|
|
||||||
{
|
|
||||||
// Deselect item
|
|
||||||
SelectedItem = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public void OnItemRenamed(ContentItem item)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public void OnItemReimported(ContentItem item)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public void OnItemDispose(ContentItem item)
|
|
||||||
{
|
|
||||||
// Deselect item
|
|
||||||
SelectedItem = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Rectangle IconRect => new Rectangle(0, 0, Height, Height);
|
private Rectangle IconRect => new Rectangle(0, 0, Height, Height);
|
||||||
|
|
||||||
private Rectangle Button1Rect => new Rectangle(Height + ButtonsOffset, 0, ButtonsSize, ButtonsSize);
|
private Rectangle Button1Rect => new Rectangle(Height + ButtonsOffset, 0, ButtonsSize, ButtonsSize);
|
||||||
@@ -341,10 +119,10 @@ namespace FlaxEditor.GUI
|
|||||||
if (CanEdit)
|
if (CanEdit)
|
||||||
Render2D.DrawSprite(style.ArrowDown, button1Rect, button1Rect.Contains(_mousePos) ? style.Foreground : style.ForegroundGrey);
|
Render2D.DrawSprite(style.ArrowDown, button1Rect, button1Rect.Contains(_mousePos) ? style.Foreground : style.ForegroundGrey);
|
||||||
|
|
||||||
if (_selectedItem != null)
|
if (Validator.SelectedItem != null)
|
||||||
{
|
{
|
||||||
// Draw item preview
|
// Draw item preview
|
||||||
_selectedItem.DrawThumbnail(ref iconRect);
|
Validator.SelectedItem.DrawThumbnail(ref iconRect);
|
||||||
|
|
||||||
// Draw buttons
|
// Draw buttons
|
||||||
if (CanEdit)
|
if (CanEdit)
|
||||||
@@ -363,7 +141,7 @@ namespace FlaxEditor.GUI
|
|||||||
{
|
{
|
||||||
Render2D.DrawText(
|
Render2D.DrawText(
|
||||||
style.FontSmall,
|
style.FontSmall,
|
||||||
_selectedItem.ShortName,
|
Validator.SelectedItem.ShortName,
|
||||||
new Rectangle(button1Rect.Right + 2, 0, sizeForTextLeft, ButtonsSize),
|
new Rectangle(button1Rect.Right + 2, 0, sizeForTextLeft, ButtonsSize),
|
||||||
style.Foreground,
|
style.Foreground,
|
||||||
TextAlignment.Near,
|
TextAlignment.Near,
|
||||||
@@ -371,7 +149,7 @@ namespace FlaxEditor.GUI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Check if has no item but has an asset (eg. virtual asset)
|
// Check if has no item but has an asset (eg. virtual asset)
|
||||||
else if (_selected)
|
else if (Validator.SelectedAsset)
|
||||||
{
|
{
|
||||||
// Draw remove button
|
// Draw remove button
|
||||||
Render2D.DrawSprite(style.Cross, button3Rect, button3Rect.Contains(_mousePos) ? style.Foreground : style.ForegroundGrey);
|
Render2D.DrawSprite(style.Cross, button3Rect, button3Rect.Contains(_mousePos) ? style.Foreground : style.ForegroundGrey);
|
||||||
@@ -380,8 +158,8 @@ namespace FlaxEditor.GUI
|
|||||||
float sizeForTextLeft = Width - button1Rect.Right;
|
float sizeForTextLeft = Width - button1Rect.Right;
|
||||||
if (sizeForTextLeft > 30)
|
if (sizeForTextLeft > 30)
|
||||||
{
|
{
|
||||||
var name = _selected.GetType().Name;
|
var name = Validator.SelectedAsset.GetType().Name;
|
||||||
if (_selected.IsVirtual)
|
if (Validator.SelectedAsset.IsVirtual)
|
||||||
name += " (virtual)";
|
name += " (virtual)";
|
||||||
Render2D.DrawText(
|
Render2D.DrawText(
|
||||||
style.FontSmall,
|
style.FontSmall,
|
||||||
@@ -395,8 +173,8 @@ namespace FlaxEditor.GUI
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// No element selected
|
// No element selected
|
||||||
Render2D.FillRectangle(iconRect, new Color(0.2f));
|
Render2D.FillRectangle(iconRect, style.BackgroundNormal);
|
||||||
Render2D.DrawText(style.FontMedium, "No asset\nselected", iconRect, Color.Wheat, TextAlignment.Center, TextAlignment.Center, TextWrapping.NoWrap, 1.0f, Height / DefaultIconSize);
|
Render2D.DrawText(style.FontMedium, "No asset\nselected", iconRect, Color.Orange, TextAlignment.Center, TextAlignment.Center, TextWrapping.NoWrap, 1.0f, Height / DefaultIconSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if drag is over
|
// Check if drag is over
|
||||||
@@ -407,9 +185,7 @@ namespace FlaxEditor.GUI
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void OnDestroy()
|
public override void OnDestroy()
|
||||||
{
|
{
|
||||||
_selectedItem?.RemoveReference(this);
|
Validator.OnDestroy();
|
||||||
_selectedItem = null;
|
|
||||||
_selected = null;
|
|
||||||
|
|
||||||
base.OnDestroy();
|
base.OnDestroy();
|
||||||
}
|
}
|
||||||
@@ -463,57 +239,57 @@ namespace FlaxEditor.GUI
|
|||||||
// Buttons logic
|
// Buttons logic
|
||||||
if (!CanEdit)
|
if (!CanEdit)
|
||||||
{
|
{
|
||||||
if (Button1Rect.Contains(location) && _selectedItem != null)
|
if (Button1Rect.Contains(location) && Validator.SelectedItem != null)
|
||||||
{
|
{
|
||||||
// Select asset
|
// Select asset
|
||||||
Editor.Instance.Windows.ContentWin.Select(_selectedItem);
|
Editor.Instance.Windows.ContentWin.Select(Validator.SelectedItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (Button1Rect.Contains(location))
|
else if (Button1Rect.Contains(location))
|
||||||
{
|
{
|
||||||
Focus();
|
Focus();
|
||||||
if (_type != ScriptType.Null)
|
if (Validator.AssetType != ScriptType.Null)
|
||||||
{
|
{
|
||||||
// Show asset picker popup
|
// Show asset picker popup
|
||||||
var popup = AssetSearchPopup.Show(this, Button1Rect.BottomLeft, IsValid, item =>
|
var popup = AssetSearchPopup.Show(this, Button1Rect.BottomLeft, Validator.IsValid, item =>
|
||||||
{
|
{
|
||||||
SelectedItem = item;
|
Validator.SelectedItem = item;
|
||||||
RootWindow.Focus();
|
RootWindow.Focus();
|
||||||
Focus();
|
Focus();
|
||||||
});
|
});
|
||||||
if (_selected != null)
|
if (Validator.SelectedAsset != null)
|
||||||
{
|
{
|
||||||
var selectedAssetName = Path.GetFileNameWithoutExtension(_selected.Path);
|
var selectedAssetName = Path.GetFileNameWithoutExtension(Validator.SelectedAsset.Path);
|
||||||
popup.ScrollToAndHighlightItemByName(selectedAssetName);
|
popup.ScrollToAndHighlightItemByName(selectedAssetName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Show content item picker popup
|
// Show content item picker popup
|
||||||
var popup = ContentSearchPopup.Show(this, Button1Rect.BottomLeft, IsValid, item =>
|
var popup = ContentSearchPopup.Show(this, Button1Rect.BottomLeft, Validator.IsValid, item =>
|
||||||
{
|
{
|
||||||
SelectedItem = item;
|
Validator.SelectedItem = item;
|
||||||
RootWindow.Focus();
|
RootWindow.Focus();
|
||||||
Focus();
|
Focus();
|
||||||
});
|
});
|
||||||
if (_selectedItem != null)
|
if (Validator.SelectedItem != null)
|
||||||
{
|
{
|
||||||
popup.ScrollToAndHighlightItemByName(_selectedItem.ShortName);
|
popup.ScrollToAndHighlightItemByName(Validator.SelectedItem.ShortName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (_selected != null || _selectedItem != null)
|
else if (Validator.SelectedAsset != null || Validator.SelectedItem != null)
|
||||||
{
|
{
|
||||||
if (Button2Rect.Contains(location) && _selectedItem != null)
|
if (Button2Rect.Contains(location) && Validator.SelectedItem != null)
|
||||||
{
|
{
|
||||||
// Select asset
|
// Select asset
|
||||||
Editor.Instance.Windows.ContentWin.Select(_selectedItem);
|
Editor.Instance.Windows.ContentWin.Select(Validator.SelectedItem);
|
||||||
}
|
}
|
||||||
else if (Button3Rect.Contains(location))
|
else if (Button3Rect.Contains(location))
|
||||||
{
|
{
|
||||||
// Deselect asset
|
// Deselect asset
|
||||||
Focus();
|
Focus();
|
||||||
SelectedItem = null;
|
Validator.SelectedItem = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -540,10 +316,10 @@ namespace FlaxEditor.GUI
|
|||||||
{
|
{
|
||||||
Focus();
|
Focus();
|
||||||
|
|
||||||
if (_selectedItem != null && IconRect.Contains(location))
|
if (Validator.SelectedItem != null && IconRect.Contains(location))
|
||||||
{
|
{
|
||||||
// Open it
|
// Open it
|
||||||
Editor.Instance.ContentEditing.Open(_selectedItem);
|
Editor.Instance.ContentEditing.Open(Validator.SelectedItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handled
|
// Handled
|
||||||
@@ -557,7 +333,7 @@ namespace FlaxEditor.GUI
|
|||||||
|
|
||||||
// Check if drop asset
|
// Check if drop asset
|
||||||
if (_dragOverElement == null)
|
if (_dragOverElement == null)
|
||||||
_dragOverElement = new DragItems(IsValid);
|
_dragOverElement = new DragItems(Validator.IsValid);
|
||||||
if (CanEdit && _dragOverElement.OnDragEnter(data))
|
if (CanEdit && _dragOverElement.OnDragEnter(data))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -590,7 +366,7 @@ namespace FlaxEditor.GUI
|
|||||||
if (CanEdit && _dragOverElement.HasValidDrag)
|
if (CanEdit && _dragOverElement.HasValidDrag)
|
||||||
{
|
{
|
||||||
// Select element
|
// Select element
|
||||||
SelectedItem = _dragOverElement.Objects[0];
|
Validator.SelectedItem = _dragOverElement.Objects[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear cache
|
// Clear cache
|
||||||
|
|||||||
@@ -39,6 +39,11 @@ namespace FlaxEditor.GUI.Dialogs
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public DialogResult Result => _result;
|
public DialogResult Result => _result;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the size of the dialog.
|
||||||
|
/// </summary>
|
||||||
|
public Float2 DialogSize => _dialogSize;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="Dialog"/> class.
|
/// Initializes a new instance of the <see cref="Dialog"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -44,11 +44,11 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
var mousePos = window.MousePosition;
|
var mousePos = window.MousePosition;
|
||||||
var previousSize = window.Size;
|
var previousSize = window.Size;
|
||||||
window.Restore();
|
window.Restore();
|
||||||
window.Position = FlaxEngine.Input.MouseScreenPosition - mousePos * window.Size / previousSize;
|
window.Position = Platform.MousePosition - mousePos * window.Size / previousSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate dragging offset and move window to the destination position
|
// Calculate dragging offset and move window to the destination position
|
||||||
var mouseScreenPosition = FlaxEngine.Input.MouseScreenPosition;
|
var mouseScreenPosition = Platform.MousePosition;
|
||||||
|
|
||||||
// If the _toMove window was not focused when initializing this window, the result vector only contains zeros
|
// If the _toMove window was not focused when initializing this window, the result vector only contains zeros
|
||||||
// and to prevent a failure, we need to perform an update for the drag offset at later time which will be done in the OnMouseMove event handler.
|
// and to prevent a failure, we need to perform an update for the drag offset at later time which will be done in the OnMouseMove event handler.
|
||||||
@@ -83,6 +83,7 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
// Enable hit window presentation
|
// Enable hit window presentation
|
||||||
Proxy.Window.RenderingEnabled = true;
|
Proxy.Window.RenderingEnabled = true;
|
||||||
Proxy.Window.Show();
|
Proxy.Window.Show();
|
||||||
|
Proxy.Window.Focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -113,7 +114,7 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
var window = _toMove.Window?.Window;
|
var window = _toMove.Window?.Window;
|
||||||
if (window == null)
|
if (window == null)
|
||||||
return;
|
return;
|
||||||
var mouse = FlaxEngine.Input.MouseScreenPosition;
|
var mouse = Platform.MousePosition;
|
||||||
|
|
||||||
// Move base window
|
// Move base window
|
||||||
window.Position = mouse - _dragOffset;
|
window.Position = mouse - _dragOffset;
|
||||||
@@ -193,7 +194,7 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
|
|
||||||
// Move window to the mouse position (with some offset for caption bar)
|
// Move window to the mouse position (with some offset for caption bar)
|
||||||
var window = (WindowRootControl)toMove.Root;
|
var window = (WindowRootControl)toMove.Root;
|
||||||
var mouse = FlaxEngine.Input.MouseScreenPosition;
|
var mouse = Platform.MousePosition;
|
||||||
window.Window.Position = mouse - new Float2(8, 8);
|
window.Window.Position = mouse - new Float2(8, 8);
|
||||||
|
|
||||||
// Get floating panel
|
// Get floating panel
|
||||||
@@ -244,7 +245,7 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
private void UpdateRects()
|
private void UpdateRects()
|
||||||
{
|
{
|
||||||
// Cache mouse position
|
// Cache mouse position
|
||||||
_mouse = FlaxEngine.Input.MouseScreenPosition;
|
_mouse = Platform.MousePosition;
|
||||||
|
|
||||||
// Check intersection with any dock panel
|
// Check intersection with any dock panel
|
||||||
var uiMouse = _mouse;
|
var uiMouse = _mouse;
|
||||||
@@ -270,15 +271,16 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
// Cache dock rectangles
|
// Cache dock rectangles
|
||||||
var size = _rectDock.Size;
|
var size = _rectDock.Size;
|
||||||
var offset = _rectDock.Location;
|
var offset = _rectDock.Location;
|
||||||
float BorderMargin = 4.0f;
|
var borderMargin = 4.0f;
|
||||||
float ProxyHintWindowsSize2 = Proxy.HintWindowsSize * 0.5f;
|
var hintWindowsSize = Proxy.HintWindowsSize * Platform.DpiScale;
|
||||||
float centerX = size.X * 0.5f;
|
var hintWindowsSize2 = hintWindowsSize * 0.5f;
|
||||||
float centerY = size.Y * 0.5f;
|
var centerX = size.X * 0.5f;
|
||||||
_rUpper = new Rectangle(centerX - ProxyHintWindowsSize2, BorderMargin, Proxy.HintWindowsSize, Proxy.HintWindowsSize) + offset;
|
var centerY = size.Y * 0.5f;
|
||||||
_rBottom = new Rectangle(centerX - ProxyHintWindowsSize2, size.Y - Proxy.HintWindowsSize - BorderMargin, Proxy.HintWindowsSize, Proxy.HintWindowsSize) + offset;
|
_rUpper = new Rectangle(centerX - hintWindowsSize2, borderMargin, hintWindowsSize, hintWindowsSize) + offset;
|
||||||
_rLeft = new Rectangle(BorderMargin, centerY - ProxyHintWindowsSize2, Proxy.HintWindowsSize, Proxy.HintWindowsSize) + offset;
|
_rBottom = new Rectangle(centerX - hintWindowsSize2, size.Y - hintWindowsSize - borderMargin, hintWindowsSize, hintWindowsSize) + offset;
|
||||||
_rRight = new Rectangle(size.X - Proxy.HintWindowsSize - BorderMargin, centerY - ProxyHintWindowsSize2, Proxy.HintWindowsSize, Proxy.HintWindowsSize) + offset;
|
_rLeft = new Rectangle(borderMargin, centerY - hintWindowsSize2, hintWindowsSize, hintWindowsSize) + offset;
|
||||||
_rCenter = new Rectangle(centerX - ProxyHintWindowsSize2, centerY - ProxyHintWindowsSize2, Proxy.HintWindowsSize, Proxy.HintWindowsSize) + offset;
|
_rRight = new Rectangle(size.X - hintWindowsSize - borderMargin, centerY - hintWindowsSize2, hintWindowsSize, hintWindowsSize) + offset;
|
||||||
|
_rCenter = new Rectangle(centerX - hintWindowsSize2, centerY - hintWindowsSize2, hintWindowsSize, hintWindowsSize) + offset;
|
||||||
|
|
||||||
// Hit test
|
// Hit test
|
||||||
DockState toSet = DockState.Float;
|
DockState toSet = DockState.Float;
|
||||||
@@ -428,7 +430,6 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
{
|
{
|
||||||
if (Window == null)
|
if (Window == null)
|
||||||
{
|
{
|
||||||
// Create proxy window
|
|
||||||
var settings = CreateWindowSettings.Default;
|
var settings = CreateWindowSettings.Default;
|
||||||
settings.Title = "DockHint.Window";
|
settings.Title = "DockHint.Window";
|
||||||
settings.Size = initSize;
|
settings.Size = initSize;
|
||||||
@@ -440,12 +441,10 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
settings.IsRegularWindow = false;
|
settings.IsRegularWindow = false;
|
||||||
settings.SupportsTransparency = true;
|
settings.SupportsTransparency = true;
|
||||||
settings.ShowInTaskbar = false;
|
settings.ShowInTaskbar = false;
|
||||||
settings.ShowAfterFirstPaint = true;
|
settings.ShowAfterFirstPaint = false;
|
||||||
settings.IsTopmost = true;
|
settings.IsTopmost = true;
|
||||||
|
|
||||||
Window = Platform.CreateWindow(ref settings);
|
Window = Platform.CreateWindow(ref settings);
|
||||||
|
|
||||||
// Set opacity and background color
|
|
||||||
Window.Opacity = 0.6f;
|
Window.Opacity = 0.6f;
|
||||||
Window.GUI.BackgroundColor = Style.Current.DragWindow;
|
Window.GUI.BackgroundColor = Style.Current.DragWindow;
|
||||||
}
|
}
|
||||||
@@ -465,7 +464,7 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
|
|
||||||
var settings = CreateWindowSettings.Default;
|
var settings = CreateWindowSettings.Default;
|
||||||
settings.Title = name;
|
settings.Title = name;
|
||||||
settings.Size = new Float2(HintWindowsSize);
|
settings.Size = new Float2(HintWindowsSize * Platform.DpiScale);
|
||||||
settings.AllowInput = false;
|
settings.AllowInput = false;
|
||||||
settings.AllowMaximize = false;
|
settings.AllowMaximize = false;
|
||||||
settings.AllowMinimize = false;
|
settings.AllowMinimize = false;
|
||||||
@@ -479,7 +478,6 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
settings.ShowAfterFirstPaint = false;
|
settings.ShowAfterFirstPaint = false;
|
||||||
|
|
||||||
win = Platform.CreateWindow(ref settings);
|
win = Platform.CreateWindow(ref settings);
|
||||||
|
|
||||||
win.Opacity = 0.6f;
|
win.Opacity = 0.6f;
|
||||||
win.GUI.BackgroundColor = Style.Current.DragWindow;
|
win.GUI.BackgroundColor = Style.Current.DragWindow;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -465,19 +465,29 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
{
|
{
|
||||||
if (Parent.Parent is SplitPanel splitter)
|
if (Parent.Parent is SplitPanel splitter)
|
||||||
{
|
{
|
||||||
// Check if has any child panels
|
// Check if there is another nested dock panel inside this dock panel and extract it here
|
||||||
var childPanel = new List<DockPanel>(_childPanels);
|
var childPanels = _childPanels.ToArray();
|
||||||
for (int i = 0; i < childPanel.Count; i++)
|
if (childPanels.Length != 0)
|
||||||
{
|
{
|
||||||
// Undock all tabs
|
// Move tabs from child panels into this one
|
||||||
var panel = childPanel[i];
|
DockWindow selectedTab = null;
|
||||||
int count = panel.TabsCount;
|
foreach (var childPanel in childPanels)
|
||||||
while (count-- > 0)
|
|
||||||
{
|
{
|
||||||
panel.GetTab(0).Close();
|
var childPanelTabs = childPanel.Tabs.ToArray();
|
||||||
|
for (var i = 0; i < childPanelTabs.Length; i++)
|
||||||
|
{
|
||||||
|
var childPanelTab = childPanelTabs[i];
|
||||||
|
if (selectedTab == null && childPanelTab.IsSelected)
|
||||||
|
selectedTab = childPanelTab;
|
||||||
|
childPanel.UndockWindow(childPanelTab);
|
||||||
|
AddTab(childPanelTab, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (selectedTab != null)
|
||||||
|
SelectTab(selectedTab);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// Unlink splitter
|
// Unlink splitter
|
||||||
var splitterParent = splitter.Parent;
|
var splitterParent = splitter.Parent;
|
||||||
Assert.IsNotNull(splitterParent);
|
Assert.IsNotNull(splitterParent);
|
||||||
@@ -496,6 +506,7 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
// Delete
|
// Delete
|
||||||
splitter.Dispose();
|
splitter.Dispose();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (!IsMaster)
|
else if (!IsMaster)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException();
|
throw new InvalidOperationException();
|
||||||
@@ -582,19 +593,17 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
/// Adds the tab.
|
/// Adds the tab.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="window">The window to insert as a tab.</param>
|
/// <param name="window">The window to insert as a tab.</param>
|
||||||
protected virtual void AddTab(DockWindow window)
|
/// <param name="autoSelect">True if auto-select newly added tab.</param>
|
||||||
|
protected virtual void AddTab(DockWindow window, bool autoSelect = true)
|
||||||
{
|
{
|
||||||
// Dock
|
|
||||||
_tabs.Add(window);
|
_tabs.Add(window);
|
||||||
window.ParentDockPanel = this;
|
window.ParentDockPanel = this;
|
||||||
|
if (autoSelect)
|
||||||
// Select tab
|
|
||||||
SelectTab(window);
|
SelectTab(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CreateTabsProxy()
|
private void CreateTabsProxy()
|
||||||
{
|
{
|
||||||
// Check if has no tabs proxy created
|
|
||||||
if (_tabsProxy == null)
|
if (_tabsProxy == null)
|
||||||
{
|
{
|
||||||
// Create proxy and make set simple full dock
|
// Create proxy and make set simple full dock
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
public class DockPanelProxy : ContainerControl
|
public class DockPanelProxy : ContainerControl
|
||||||
{
|
{
|
||||||
private DockPanel _panel;
|
private DockPanel _panel;
|
||||||
|
private double _dragEnterTime = -1;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The is mouse down flag (left button).
|
/// The is mouse down flag (left button).
|
||||||
@@ -477,11 +478,7 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
var result = base.OnDragEnter(ref location, data);
|
var result = base.OnDragEnter(ref location, data);
|
||||||
if (result != DragDropEffect.None)
|
if (result != DragDropEffect.None)
|
||||||
return result;
|
return result;
|
||||||
|
return TrySelectTabUnderLocation(ref location);
|
||||||
if (TrySelectTabUnderLocation(ref location))
|
|
||||||
return DragDropEffect.Move;
|
|
||||||
|
|
||||||
return DragDropEffect.None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@@ -490,11 +487,15 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
var result = base.OnDragMove(ref location, data);
|
var result = base.OnDragMove(ref location, data);
|
||||||
if (result != DragDropEffect.None)
|
if (result != DragDropEffect.None)
|
||||||
return result;
|
return result;
|
||||||
|
return TrySelectTabUnderLocation(ref location);
|
||||||
|
}
|
||||||
|
|
||||||
if (TrySelectTabUnderLocation(ref location))
|
/// <inheritdoc />
|
||||||
return DragDropEffect.Move;
|
public override void OnDragLeave()
|
||||||
|
{
|
||||||
|
_dragEnterTime = -1;
|
||||||
|
|
||||||
return DragDropEffect.None;
|
base.OnDragLeave();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@@ -503,17 +504,25 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
rect = new Rectangle(0, DockPanel.DefaultHeaderHeight, Width, Height - DockPanel.DefaultHeaderHeight);
|
rect = new Rectangle(0, DockPanel.DefaultHeaderHeight, Width, Height - DockPanel.DefaultHeaderHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool TrySelectTabUnderLocation(ref Float2 location)
|
private DragDropEffect TrySelectTabUnderLocation(ref Float2 location)
|
||||||
{
|
{
|
||||||
var tab = GetTabAtPos(location, out _);
|
var tab = GetTabAtPos(location, out _);
|
||||||
if (tab != null)
|
if (tab != null)
|
||||||
{
|
{
|
||||||
|
// Auto-select tab only if drag takes some time
|
||||||
|
var time = Platform.TimeSeconds;
|
||||||
|
if (_dragEnterTime < 0)
|
||||||
|
_dragEnterTime = time;
|
||||||
|
if (time - _dragEnterTime < 0.3f)
|
||||||
|
return DragDropEffect.Link;
|
||||||
|
_dragEnterTime = -1;
|
||||||
|
|
||||||
_panel.SelectTab(tab);
|
_panel.SelectTab(tab);
|
||||||
Update(0); // Fake update
|
Update(0); // Fake update
|
||||||
return true;
|
return DragDropEffect.Move;
|
||||||
}
|
}
|
||||||
|
_dragEnterTime = -1;
|
||||||
return false;
|
return DragDropEffect.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ShowContextMenu(DockWindow tab, ref Float2 location)
|
private void ShowContextMenu(DockWindow tab, ref Float2 location)
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
settings.Size = size;
|
settings.Size = size;
|
||||||
settings.Position = location;
|
settings.Position = location;
|
||||||
settings.MinimumSize = new Float2(1);
|
settings.MinimumSize = new Float2(1);
|
||||||
settings.MaximumSize = new Float2(4096);
|
settings.MaximumSize = Float2.Zero; // Unlimited size
|
||||||
settings.Fullscreen = false;
|
settings.Fullscreen = false;
|
||||||
settings.HasBorder = true;
|
settings.HasBorder = true;
|
||||||
settings.SupportsTransparency = false;
|
settings.SupportsTransparency = false;
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ namespace FlaxEditor.GUI.Input
|
|||||||
[HideInEditor]
|
[HideInEditor]
|
||||||
public class ColorValueBox : Control
|
public class ColorValueBox : Control
|
||||||
{
|
{
|
||||||
|
private bool _isMouseDown;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Delegate function used for the color picker events handling.
|
/// Delegate function used for the color picker events handling.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -134,11 +136,22 @@ namespace FlaxEditor.GUI.Input
|
|||||||
Render2D.DrawRectangle(r, IsMouseOver || IsNavFocused ? style.BackgroundSelected : Color.Black);
|
Render2D.DrawRectangle(r, IsMouseOver || IsNavFocused ? style.BackgroundSelected : Color.Black);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override bool OnMouseDown(Float2 location, MouseButton button)
|
||||||
|
{
|
||||||
|
_isMouseDown = true;
|
||||||
|
return base.OnMouseDown(location, button);
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override bool OnMouseUp(Float2 location, MouseButton button)
|
public override bool OnMouseUp(Float2 location, MouseButton button)
|
||||||
{
|
{
|
||||||
|
if (_isMouseDown)
|
||||||
|
{
|
||||||
|
_isMouseDown = false;
|
||||||
Focus();
|
Focus();
|
||||||
OnSubmit();
|
OnSubmit();
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -100,9 +100,10 @@ namespace FlaxEditor.GUI
|
|||||||
AutoResize = true;
|
AutoResize = true;
|
||||||
Offsets = new Margin(0, 0, 0, IconSize);
|
Offsets = new Margin(0, 0, 0, IconSize);
|
||||||
|
|
||||||
_mouseOverColor = style.Foreground;
|
// Ignoring style on purpose (style would make sense if the icons were white, but they are colored)
|
||||||
_selectedColor = style.Foreground;
|
_mouseOverColor = new Color(0.8f, 0.8f, 0.8f, 1f);
|
||||||
_defaultColor = style.ForegroundGrey;
|
_selectedColor = Color.White;
|
||||||
|
_defaultColor = new Color(0.7f, 0.7f, 0.7f, 0.5f);
|
||||||
|
|
||||||
for (int i = 0; i < platforms.Length; i++)
|
for (int i = 0; i < platforms.Length; i++)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ namespace FlaxEditor.GUI
|
|||||||
rect.Width -= leftDepthMargin;
|
rect.Width -= leftDepthMargin;
|
||||||
|
|
||||||
Render2D.PushClip(rect);
|
Render2D.PushClip(rect);
|
||||||
Render2D.DrawText(style.FontMedium, text, rect, Color.White, column.CellAlignment, TextAlignment.Center);
|
Render2D.DrawText(style.FontMedium, text, rect, style.Foreground, column.CellAlignment, TextAlignment.Center);
|
||||||
Render2D.PopClip();
|
Render2D.PopClip();
|
||||||
|
|
||||||
x += width;
|
x += width;
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ namespace FlaxEditor.GUI.Tabs
|
|||||||
[HideInEditor]
|
[HideInEditor]
|
||||||
public class Tab : ContainerControl
|
public class Tab : ContainerControl
|
||||||
{
|
{
|
||||||
|
internal Tabs _selectedInTabs;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the text.
|
/// Gets or sets the text.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -86,5 +88,25 @@ namespace FlaxEditor.GUI.Tabs
|
|||||||
{
|
{
|
||||||
return new Tabs.TabHeader((Tabs)Parent, this);
|
return new Tabs.TabHeader((Tabs)Parent, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void OnParentChangedInternal()
|
||||||
|
{
|
||||||
|
if (_selectedInTabs != null)
|
||||||
|
_selectedInTabs.SelectedTab = null;
|
||||||
|
|
||||||
|
base.OnParentChangedInternal();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnDestroy()
|
||||||
|
{
|
||||||
|
if (IsDisposing)
|
||||||
|
return;
|
||||||
|
if (_selectedInTabs != null)
|
||||||
|
_selectedInTabs.SelectedTab = null;
|
||||||
|
|
||||||
|
base.OnDestroy();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -239,7 +239,7 @@ namespace FlaxEditor.GUI.Tabs
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public Tab SelectedTab
|
public Tab SelectedTab
|
||||||
{
|
{
|
||||||
get => _selectedIndex == -1 && Children.Count > _selectedIndex + 1 ? null : Children[_selectedIndex + 1] as Tab;
|
get => _selectedIndex < 0 || Children.Count <= _selectedIndex ? null : Children[_selectedIndex + 1] as Tab;
|
||||||
set => SelectedTabIndex = value != null ? Children.IndexOf(value) - 1 : -1;
|
set => SelectedTabIndex = value != null ? Children.IndexOf(value) - 1 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -263,7 +263,12 @@ namespace FlaxEditor.GUI.Tabs
|
|||||||
// Check if index will change
|
// Check if index will change
|
||||||
if (_selectedIndex != index)
|
if (_selectedIndex != index)
|
||||||
{
|
{
|
||||||
SelectedTab?.OnDeselected();
|
var prev = SelectedTab;
|
||||||
|
if (prev != null)
|
||||||
|
{
|
||||||
|
prev._selectedInTabs = null;
|
||||||
|
prev.OnDeselected();
|
||||||
|
}
|
||||||
_selectedIndex = index;
|
_selectedIndex = index;
|
||||||
PerformLayout();
|
PerformLayout();
|
||||||
OnSelectedTabChanged();
|
OnSelectedTabChanged();
|
||||||
@@ -342,8 +347,13 @@ namespace FlaxEditor.GUI.Tabs
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
protected virtual void OnSelectedTabChanged()
|
protected virtual void OnSelectedTabChanged()
|
||||||
{
|
{
|
||||||
|
var selectedTab = SelectedTab;
|
||||||
SelectedTabChanged?.Invoke(this);
|
SelectedTabChanged?.Invoke(this);
|
||||||
SelectedTab?.OnSelected();
|
if (selectedTab != null)
|
||||||
|
{
|
||||||
|
selectedTab._selectedInTabs = this;
|
||||||
|
selectedTab.OnSelected();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|||||||
@@ -627,10 +627,11 @@ namespace FlaxEditor.GUI.Timeline
|
|||||||
Parent = this
|
Parent = this
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var style = Style.Current;
|
||||||
var headerTopArea = new ContainerControl
|
var headerTopArea = new ContainerControl
|
||||||
{
|
{
|
||||||
AutoFocus = false,
|
AutoFocus = false,
|
||||||
BackgroundColor = Style.Current.LightBackground,
|
BackgroundColor = style.LightBackground,
|
||||||
AnchorPreset = AnchorPresets.HorizontalStretchTop,
|
AnchorPreset = AnchorPresets.HorizontalStretchTop,
|
||||||
Offsets = new Margin(0, 0, 0, HeaderTopAreaHeight),
|
Offsets = new Margin(0, 0, 0, HeaderTopAreaHeight),
|
||||||
Parent = _splitter.Panel1
|
Parent = _splitter.Panel1
|
||||||
@@ -683,7 +684,7 @@ namespace FlaxEditor.GUI.Timeline
|
|||||||
{
|
{
|
||||||
AutoFocus = false,
|
AutoFocus = false,
|
||||||
ClipChildren = false,
|
ClipChildren = false,
|
||||||
BackgroundColor = Style.Current.LightBackground,
|
BackgroundColor = style.LightBackground,
|
||||||
AnchorPreset = AnchorPresets.HorizontalStretchBottom,
|
AnchorPreset = AnchorPresets.HorizontalStretchBottom,
|
||||||
Offsets = new Margin(0, 0, -playbackButtonsSize, playbackButtonsSize),
|
Offsets = new Margin(0, 0, -playbackButtonsSize, playbackButtonsSize),
|
||||||
Parent = _splitter.Panel1
|
Parent = _splitter.Panel1
|
||||||
@@ -845,7 +846,7 @@ namespace FlaxEditor.GUI.Timeline
|
|||||||
_timeIntervalsHeader = new TimeIntervalsHeader(this)
|
_timeIntervalsHeader = new TimeIntervalsHeader(this)
|
||||||
{
|
{
|
||||||
AutoFocus = false,
|
AutoFocus = false,
|
||||||
BackgroundColor = Style.Current.Background.RGBMultiplied(0.9f),
|
BackgroundColor = style.Background.RGBMultiplied(0.9f),
|
||||||
AnchorPreset = AnchorPresets.HorizontalStretchTop,
|
AnchorPreset = AnchorPresets.HorizontalStretchTop,
|
||||||
Offsets = new Margin(0, 0, 0, HeaderTopAreaHeight),
|
Offsets = new Margin(0, 0, 0, HeaderTopAreaHeight),
|
||||||
Parent = _splitter.Panel2
|
Parent = _splitter.Panel2
|
||||||
@@ -854,7 +855,7 @@ namespace FlaxEditor.GUI.Timeline
|
|||||||
{
|
{
|
||||||
AutoFocus = false,
|
AutoFocus = false,
|
||||||
ClipChildren = false,
|
ClipChildren = false,
|
||||||
BackgroundColor = Style.Current.Background.RGBMultiplied(0.7f),
|
BackgroundColor = style.Background.RGBMultiplied(0.7f),
|
||||||
AnchorPreset = AnchorPresets.StretchAll,
|
AnchorPreset = AnchorPresets.StretchAll,
|
||||||
Offsets = new Margin(0, 0, HeaderTopAreaHeight, 0),
|
Offsets = new Margin(0, 0, HeaderTopAreaHeight, 0),
|
||||||
Parent = _splitter.Panel2
|
Parent = _splitter.Panel2
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ namespace FlaxEditor.GUI.Timeline.Tracks
|
|||||||
if (AssetID == value?.ID)
|
if (AssetID == value?.ID)
|
||||||
return;
|
return;
|
||||||
AssetID = value?.ID ?? Guid.Empty;
|
AssetID = value?.ID ?? Guid.Empty;
|
||||||
_picker.SelectedAsset = value;
|
_picker.Validator.SelectedAsset = value;
|
||||||
OnAssetChanged();
|
OnAssetChanged();
|
||||||
Timeline?.MarkAsEdited();
|
Timeline?.MarkAsEdited();
|
||||||
}
|
}
|
||||||
@@ -63,10 +63,10 @@ namespace FlaxEditor.GUI.Timeline.Tracks
|
|||||||
|
|
||||||
private void OnPickerSelectedItemChanged()
|
private void OnPickerSelectedItemChanged()
|
||||||
{
|
{
|
||||||
if (Asset == (TAsset)_picker.SelectedAsset)
|
if (Asset == (TAsset)_picker.Validator.SelectedAsset)
|
||||||
return;
|
return;
|
||||||
using (new TrackUndoBlock(this))
|
using (new TrackUndoBlock(this))
|
||||||
Asset = (TAsset)_picker.SelectedAsset;
|
Asset = (TAsset)_picker.Validator.SelectedAsset;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -776,12 +776,21 @@ namespace FlaxEditor.GUI.Tree
|
|||||||
// Check if mouse hits arrow
|
// Check if mouse hits arrow
|
||||||
if (_mouseOverArrow && HasAnyVisibleChild)
|
if (_mouseOverArrow && HasAnyVisibleChild)
|
||||||
{
|
{
|
||||||
// Toggle open state
|
if (ParentTree.Root.GetKey(KeyboardKeys.Alt))
|
||||||
|
{
|
||||||
|
if (_opened)
|
||||||
|
CollapseAll();
|
||||||
|
else
|
||||||
|
ExpandAll();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if (_opened)
|
if (_opened)
|
||||||
Collapse();
|
Collapse();
|
||||||
else
|
else
|
||||||
Expand();
|
Expand();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check if mouse hits bar
|
// Check if mouse hits bar
|
||||||
if (button == MouseButton.Right && TestHeaderHit(ref location))
|
if (button == MouseButton.Right && TestHeaderHit(ref location))
|
||||||
|
|||||||
@@ -106,5 +106,11 @@ namespace FlaxEditor.Gizmo
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="nodes">The nodes to select</param>
|
/// <param name="nodes">The nodes to select</param>
|
||||||
void Select(List<SceneGraph.SceneGraphNode> nodes);
|
void Select(List<SceneGraph.SceneGraphNode> nodes);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Spawns the actor in the viewport hierarchy.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="actor">The new actor to spawn.</param>
|
||||||
|
void Spawn(Actor actor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -111,7 +111,8 @@ namespace FlaxEditor.Gizmo
|
|||||||
if (isSelected)
|
if (isSelected)
|
||||||
{
|
{
|
||||||
GetSelectedObjectsBounds(out var selectionBounds, out _);
|
GetSelectedObjectsBounds(out var selectionBounds, out _);
|
||||||
ray.Position = ray.GetPoint(selectionBounds.Size.Y * 0.5f);
|
var offset = Mathf.Max(selectionBounds.Size.Y * 0.5f, 1.0f);
|
||||||
|
ray.Position = ray.GetPoint(offset);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -513,7 +513,9 @@ DEFINE_INTERNAL_CALL(void) EditorInternal_RunVisualScriptBreakpointLoopTick(floa
|
|||||||
WindowsManager::WindowsLocker.Unlock();
|
WindowsManager::WindowsLocker.Unlock();
|
||||||
}
|
}
|
||||||
WindowsManager::WindowsLocker.Lock();
|
WindowsManager::WindowsLocker.Lock();
|
||||||
for (auto& win : WindowsManager::Windows)
|
Array<Window*, InlinedAllocation<32>> windows;
|
||||||
|
windows.Add(WindowsManager::Windows);
|
||||||
|
for (Window* win : windows)
|
||||||
{
|
{
|
||||||
if (win->IsVisible())
|
if (win->IsVisible())
|
||||||
win->OnUpdate(deltaTime);
|
win->OnUpdate(deltaTime);
|
||||||
|
|||||||
@@ -330,14 +330,15 @@ bool ManagedEditor::CanReloadScripts()
|
|||||||
|
|
||||||
bool ManagedEditor::CanAutoBuildCSG()
|
bool ManagedEditor::CanAutoBuildCSG()
|
||||||
{
|
{
|
||||||
|
if (!ManagedEditorOptions.AutoRebuildCSG)
|
||||||
|
return false;
|
||||||
|
|
||||||
// Skip calls from non-managed thread (eg. physics worker)
|
// Skip calls from non-managed thread (eg. physics worker)
|
||||||
if (!MCore::Thread::IsAttached())
|
if (!MCore::Thread::IsAttached())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!HasManagedInstance())
|
if (!HasManagedInstance())
|
||||||
return false;
|
return false;
|
||||||
if (!ManagedEditorOptions.AutoRebuildCSG)
|
|
||||||
return false;
|
|
||||||
if (Internal_CanAutoBuildCSG == nullptr)
|
if (Internal_CanAutoBuildCSG == nullptr)
|
||||||
{
|
{
|
||||||
Internal_CanAutoBuildCSG = GetClass()->GetMethod("Internal_CanAutoBuildCSG");
|
Internal_CanAutoBuildCSG = GetClass()->GetMethod("Internal_CanAutoBuildCSG");
|
||||||
@@ -348,14 +349,15 @@ bool ManagedEditor::CanAutoBuildCSG()
|
|||||||
|
|
||||||
bool ManagedEditor::CanAutoBuildNavMesh()
|
bool ManagedEditor::CanAutoBuildNavMesh()
|
||||||
{
|
{
|
||||||
|
if (!ManagedEditorOptions.AutoRebuildNavMesh)
|
||||||
|
return false;
|
||||||
|
|
||||||
// Skip calls from non-managed thread (eg. physics worker)
|
// Skip calls from non-managed thread (eg. physics worker)
|
||||||
if (!MCore::Thread::IsAttached())
|
if (!MCore::Thread::IsAttached())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!HasManagedInstance())
|
if (!HasManagedInstance())
|
||||||
return false;
|
return false;
|
||||||
if (!ManagedEditorOptions.AutoRebuildNavMesh)
|
|
||||||
return false;
|
|
||||||
if (Internal_CanAutoBuildNavMesh == nullptr)
|
if (Internal_CanAutoBuildNavMesh == nullptr)
|
||||||
{
|
{
|
||||||
Internal_CanAutoBuildNavMesh = GetClass()->GetMethod("Internal_CanAutoBuildNavMesh");
|
Internal_CanAutoBuildNavMesh = GetClass()->GetMethod("Internal_CanAutoBuildNavMesh");
|
||||||
|
|||||||
@@ -124,6 +124,7 @@ namespace FlaxEditor.Modules
|
|||||||
if (!Editor.StateMachine.CurrentState.CanEditScene)
|
if (!Editor.StateMachine.CurrentState.CanEditScene)
|
||||||
return;
|
return;
|
||||||
undo = Editor.Undo;
|
undo = Editor.Undo;
|
||||||
|
Editor.Scene.MarkSceneEdited(actor.Scene);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Record undo for prefab creating (backend links the target instance with the prefab)
|
// Record undo for prefab creating (backend links the target instance with the prefab)
|
||||||
|
|||||||
@@ -242,7 +242,6 @@ namespace FlaxEditor.Modules
|
|||||||
/// <param name="additive">True if don't close opened scenes and just add new scene to them, otherwise will release current scenes and load single one.</param>
|
/// <param name="additive">True if don't close opened scenes and just add new scene to them, otherwise will release current scenes and load single one.</param>
|
||||||
public void OpenScene(Guid sceneId, bool additive = false)
|
public void OpenScene(Guid sceneId, bool additive = false)
|
||||||
{
|
{
|
||||||
// Check if cannot change scene now
|
|
||||||
if (!Editor.StateMachine.CurrentState.CanChangeScene)
|
if (!Editor.StateMachine.CurrentState.CanChangeScene)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -266,13 +265,35 @@ namespace FlaxEditor.Modules
|
|||||||
Editor.StateMachine.ChangingScenesState.LoadScene(sceneId, additive);
|
Editor.StateMachine.ChangingScenesState.LoadScene(sceneId, additive);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reload all loaded scenes.
|
||||||
|
/// </summary>
|
||||||
|
public void ReloadScenes()
|
||||||
|
{
|
||||||
|
if (!Editor.StateMachine.CurrentState.CanChangeScene)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!Editor.IsPlayMode)
|
||||||
|
{
|
||||||
|
if (CheckSaveBeforeClose())
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reload scenes
|
||||||
|
foreach (var scene in Level.Scenes)
|
||||||
|
{
|
||||||
|
var sceneId = scene.ID;
|
||||||
|
Level.UnloadScene(scene);
|
||||||
|
Level.LoadScene(sceneId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Closes scene (async).
|
/// Closes scene (async).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="scene">The scene.</param>
|
/// <param name="scene">The scene.</param>
|
||||||
public void CloseScene(Scene scene)
|
public void CloseScene(Scene scene)
|
||||||
{
|
{
|
||||||
// Check if cannot change scene now
|
|
||||||
if (!Editor.StateMachine.CurrentState.CanChangeScene)
|
if (!Editor.StateMachine.CurrentState.CanChangeScene)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -296,7 +317,6 @@ namespace FlaxEditor.Modules
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void CloseAllScenes()
|
public void CloseAllScenes()
|
||||||
{
|
{
|
||||||
// Check if cannot change scene now
|
|
||||||
if (!Editor.StateMachine.CurrentState.CanChangeScene)
|
if (!Editor.StateMachine.CurrentState.CanChangeScene)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -321,7 +341,6 @@ namespace FlaxEditor.Modules
|
|||||||
/// <param name="scene">The scene to not close.</param>
|
/// <param name="scene">The scene to not close.</param>
|
||||||
public void CloseAllScenesExcept(Scene scene)
|
public void CloseAllScenesExcept(Scene scene)
|
||||||
{
|
{
|
||||||
// Check if cannot change scene now
|
|
||||||
if (!Editor.StateMachine.CurrentState.CanChangeScene)
|
if (!Editor.StateMachine.CurrentState.CanChangeScene)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@@ -147,6 +147,17 @@ namespace FlaxEditor.Modules.SourceCodeEditing
|
|||||||
}
|
}
|
||||||
if (key != null)
|
if (key != null)
|
||||||
xml.TryGetValue(key, out text);
|
xml.TryGetValue(key, out text);
|
||||||
|
|
||||||
|
// Customize tooltips for properties to be more human-readable in UI
|
||||||
|
if (text != null && memberType.HasFlag(MemberTypes.Property) && text.StartsWith("Gets or sets ", StringComparison.Ordinal))
|
||||||
|
{
|
||||||
|
text = text.Substring(13);
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
fixed (char* e = text)
|
||||||
|
e[0] = char.ToUpper(e[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ namespace FlaxEditor.Modules
|
|||||||
ContextMenuSingleSelectGroup<int> _numberOfClientsGroup = new ContextMenuSingleSelectGroup<int>();
|
ContextMenuSingleSelectGroup<int> _numberOfClientsGroup = new ContextMenuSingleSelectGroup<int>();
|
||||||
|
|
||||||
private ContextMenuButton _menuFileSaveScenes;
|
private ContextMenuButton _menuFileSaveScenes;
|
||||||
|
private ContextMenuButton _menuFileReloadScenes;
|
||||||
private ContextMenuButton _menuFileCloseScenes;
|
private ContextMenuButton _menuFileCloseScenes;
|
||||||
private ContextMenuButton _menuFileOpenScriptsProject;
|
private ContextMenuButton _menuFileOpenScriptsProject;
|
||||||
private ContextMenuButton _menuFileGenerateScriptsProjectFiles;
|
private ContextMenuButton _menuFileGenerateScriptsProjectFiles;
|
||||||
@@ -470,13 +471,13 @@ namespace FlaxEditor.Modules
|
|||||||
// Place dialog nearby the target control
|
// Place dialog nearby the target control
|
||||||
var targetControlDesktopCenter = targetControl.PointToScreen(targetControl.Size * 0.5f);
|
var targetControlDesktopCenter = targetControl.PointToScreen(targetControl.Size * 0.5f);
|
||||||
var desktopSize = Platform.GetMonitorBounds(targetControlDesktopCenter);
|
var desktopSize = Platform.GetMonitorBounds(targetControlDesktopCenter);
|
||||||
var pos = targetControlDesktopCenter + new Float2(10.0f, -dialog.Height * 0.5f);
|
var pos = targetControlDesktopCenter + new Float2(10.0f, -dialog.DialogSize.Y * 0.5f);
|
||||||
var dialogEnd = pos + dialog.Size;
|
var dialogEnd = pos + dialog.DialogSize;
|
||||||
var desktopEnd = desktopSize.BottomRight - new Float2(10.0f);
|
var desktopEnd = desktopSize.BottomRight - new Float2(10.0f);
|
||||||
if (dialogEnd.X >= desktopEnd.X || dialogEnd.Y >= desktopEnd.Y)
|
if (dialogEnd.X >= desktopEnd.X || dialogEnd.Y >= desktopEnd.Y)
|
||||||
pos = targetControl.PointToScreen(Float2.Zero) - new Float2(10.0f + dialog.Width, dialog.Height);
|
pos = targetControl.PointToScreen(Float2.Zero) - new Float2(10.0f + dialog.DialogSize.X, dialog.DialogSize.Y);
|
||||||
var desktopBounds = Platform.VirtualDesktopBounds;
|
var desktopBounds = Platform.VirtualDesktopBounds;
|
||||||
pos = Float2.Clamp(pos, desktopBounds.UpperLeft, desktopBounds.BottomRight - dialog.Size);
|
pos = Float2.Clamp(pos, desktopBounds.UpperLeft, desktopBounds.BottomRight - dialog.DialogSize);
|
||||||
dialog.RootWindow.Window.Position = pos;
|
dialog.RootWindow.Window.Position = pos;
|
||||||
|
|
||||||
// Register for context menu (prevent auto-closing context menu when selecting color)
|
// Register for context menu (prevent auto-closing context menu when selecting color)
|
||||||
@@ -527,6 +528,7 @@ namespace FlaxEditor.Modules
|
|||||||
_menuFileSaveAll = cm.AddButton("Save All", inputOptions.Save, Editor.SaveAll);
|
_menuFileSaveAll = cm.AddButton("Save All", inputOptions.Save, Editor.SaveAll);
|
||||||
_menuFileSaveScenes = cm.AddButton("Save scenes", inputOptions.SaveScenes, Editor.Scene.SaveScenes);
|
_menuFileSaveScenes = cm.AddButton("Save scenes", inputOptions.SaveScenes, Editor.Scene.SaveScenes);
|
||||||
_menuFileCloseScenes = cm.AddButton("Close scenes", inputOptions.CloseScenes, Editor.Scene.CloseAllScenes);
|
_menuFileCloseScenes = cm.AddButton("Close scenes", inputOptions.CloseScenes, Editor.Scene.CloseAllScenes);
|
||||||
|
_menuFileReloadScenes = cm.AddButton("Reload scenes", Editor.Scene.ReloadScenes);
|
||||||
cm.AddSeparator();
|
cm.AddSeparator();
|
||||||
_menuFileOpenScriptsProject = cm.AddButton("Open scripts project", inputOptions.OpenScriptsProject, Editor.CodeEditing.OpenSolution);
|
_menuFileOpenScriptsProject = cm.AddButton("Open scripts project", inputOptions.OpenScriptsProject, Editor.CodeEditing.OpenSolution);
|
||||||
_menuFileGenerateScriptsProjectFiles = cm.AddButton("Generate scripts project files", inputOptions.GenerateScriptsProject, Editor.ProgressReporting.GenerateScriptsProjectFiles.RunAsync);
|
_menuFileGenerateScriptsProjectFiles = cm.AddButton("Generate scripts project files", inputOptions.GenerateScriptsProject, Editor.ProgressReporting.GenerateScriptsProjectFiles.RunAsync);
|
||||||
@@ -830,6 +832,7 @@ namespace FlaxEditor.Modules
|
|||||||
|
|
||||||
_menuFileSaveScenes.Enabled = hasOpenedScene;
|
_menuFileSaveScenes.Enabled = hasOpenedScene;
|
||||||
_menuFileCloseScenes.Enabled = hasOpenedScene;
|
_menuFileCloseScenes.Enabled = hasOpenedScene;
|
||||||
|
_menuFileReloadScenes.Enabled = hasOpenedScene;
|
||||||
_menuFileGenerateScriptsProjectFiles.Enabled = !Editor.ProgressReporting.GenerateScriptsProjectFiles.IsActive;
|
_menuFileGenerateScriptsProjectFiles.Enabled = !Editor.ProgressReporting.GenerateScriptsProjectFiles.IsActive;
|
||||||
|
|
||||||
c.PerformLayout();
|
c.PerformLayout();
|
||||||
|
|||||||
@@ -171,9 +171,13 @@ namespace FlaxEditor.Modules
|
|||||||
var mainWindow = MainWindow;
|
var mainWindow = MainWindow;
|
||||||
if (mainWindow)
|
if (mainWindow)
|
||||||
{
|
{
|
||||||
var projectPath = Globals.ProjectFolder.Replace('/', '\\');
|
var projectPath = Globals.ProjectFolder;
|
||||||
var platformBit = Platform.Is64BitApp ? "64" : "32";
|
#if PLATFORM_WINDOWS
|
||||||
var title = string.Format("Flax Editor - \'{0}\' ({1}-bit)", projectPath, platformBit);
|
projectPath = projectPath.Replace('/', '\\');
|
||||||
|
#endif
|
||||||
|
var engineVersion = Editor.EngineProject.Version;
|
||||||
|
var engineVersionText = engineVersion.Revision > 0 ? $"{engineVersion.Major}.{engineVersion.Minor}.{engineVersion.Revision}" : $"{engineVersion.Major}.{engineVersion.Minor}";
|
||||||
|
var title = $"Flax Editor {engineVersionText} - \'{projectPath}\'";
|
||||||
mainWindow.Title = title;
|
mainWindow.Title = title;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -237,7 +241,11 @@ namespace FlaxEditor.Modules
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void LoadDefaultLayout()
|
public void LoadDefaultLayout()
|
||||||
{
|
{
|
||||||
LoadLayout(StringUtils.CombinePaths(Globals.EngineContentFolder, "Editor/LayoutDefault.xml"));
|
var path = StringUtils.CombinePaths(Globals.EngineContentFolder, "Editor/LayoutDefault.xml");
|
||||||
|
if (File.Exists(path))
|
||||||
|
{
|
||||||
|
LoadLayout(path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -731,7 +739,6 @@ namespace FlaxEditor.Modules
|
|||||||
settings.Size = Platform.DesktopSize * 0.75f;
|
settings.Size = Platform.DesktopSize * 0.75f;
|
||||||
settings.StartPosition = WindowStartPosition.CenterScreen;
|
settings.StartPosition = WindowStartPosition.CenterScreen;
|
||||||
settings.ShowAfterFirstPaint = true;
|
settings.ShowAfterFirstPaint = true;
|
||||||
|
|
||||||
#if PLATFORM_WINDOWS
|
#if PLATFORM_WINDOWS
|
||||||
if (!Editor.Instance.Options.Options.Interface.UseNativeWindowSystem)
|
if (!Editor.Instance.Options.Options.Interface.UseNativeWindowSystem)
|
||||||
{
|
{
|
||||||
@@ -743,12 +750,9 @@ namespace FlaxEditor.Modules
|
|||||||
#elif PLATFORM_LINUX
|
#elif PLATFORM_LINUX
|
||||||
settings.HasBorder = false;
|
settings.HasBorder = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
MainWindow = Platform.CreateWindow(ref settings);
|
MainWindow = Platform.CreateWindow(ref settings);
|
||||||
|
|
||||||
if (MainWindow == null)
|
if (MainWindow == null)
|
||||||
{
|
{
|
||||||
// Error
|
|
||||||
Editor.LogError("Failed to create editor main window!");
|
Editor.LogError("Failed to create editor main window!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -259,10 +259,7 @@ namespace FlaxEditor.Options
|
|||||||
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
|
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
|
||||||
{
|
{
|
||||||
if (sourceType == typeof(string))
|
if (sourceType == typeof(string))
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
return base.CanConvertFrom(context, sourceType);
|
return base.CanConvertFrom(context, sourceType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -270,9 +267,7 @@ namespace FlaxEditor.Options
|
|||||||
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
|
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
|
||||||
{
|
{
|
||||||
if (destinationType == typeof(string))
|
if (destinationType == typeof(string))
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
return base.CanConvertTo(context, destinationType);
|
return base.CanConvertTo(context, destinationType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -284,7 +279,6 @@ namespace FlaxEditor.Options
|
|||||||
InputBinding.TryParse(str, out var result);
|
InputBinding.TryParse(str, out var result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
return base.ConvertFrom(context, culture, value);
|
return base.ConvertFrom(context, culture, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -295,7 +289,6 @@ namespace FlaxEditor.Options
|
|||||||
{
|
{
|
||||||
return ((InputBinding)value).ToString();
|
return ((InputBinding)value).ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
return base.ConvertTo(context, culture, value, destinationType);
|
return base.ConvertTo(context, culture, value, destinationType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,6 +76,10 @@ namespace FlaxEditor.Options
|
|||||||
[EditorDisplay("Common"), EditorOrder(230)]
|
[EditorDisplay("Common"), EditorOrder(230)]
|
||||||
public InputBinding RotateSelection = new InputBinding(KeyboardKeys.R);
|
public InputBinding RotateSelection = new InputBinding(KeyboardKeys.R);
|
||||||
|
|
||||||
|
[DefaultValue(typeof(InputBinding), "F11")]
|
||||||
|
[EditorDisplay("Common"), EditorOrder(240)]
|
||||||
|
public InputBinding ToggleFullscreen = new InputBinding(KeyboardKeys.F11);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region File
|
#region File
|
||||||
@@ -208,16 +212,20 @@ namespace FlaxEditor.Options
|
|||||||
[EditorDisplay("Debugger", "Continue"), EditorOrder(810)]
|
[EditorDisplay("Debugger", "Continue"), EditorOrder(810)]
|
||||||
public InputBinding DebuggerContinue = new InputBinding(KeyboardKeys.F5);
|
public InputBinding DebuggerContinue = new InputBinding(KeyboardKeys.F5);
|
||||||
|
|
||||||
|
[DefaultValue(typeof(InputBinding), "Shift+F11")]
|
||||||
|
[EditorDisplay("Debugger", "Unlock mouse in Play Mode"), EditorOrder(820)]
|
||||||
|
public InputBinding DebuggerUnlockMouse = new InputBinding(KeyboardKeys.F11, KeyboardKeys.Shift);
|
||||||
|
|
||||||
[DefaultValue(typeof(InputBinding), "F10")]
|
[DefaultValue(typeof(InputBinding), "F10")]
|
||||||
[EditorDisplay("Debugger", "Step Over"), EditorOrder(820)]
|
[EditorDisplay("Debugger", "Step Over"), EditorOrder(830)]
|
||||||
public InputBinding DebuggerStepOver = new InputBinding(KeyboardKeys.F10);
|
public InputBinding DebuggerStepOver = new InputBinding(KeyboardKeys.F10);
|
||||||
|
|
||||||
[DefaultValue(typeof(InputBinding), "F11")]
|
[DefaultValue(typeof(InputBinding), "F11")]
|
||||||
[EditorDisplay("Debugger", "Step Into"), EditorOrder(830)]
|
[EditorDisplay("Debugger", "Step Into"), EditorOrder(840)]
|
||||||
public InputBinding DebuggerStepInto = new InputBinding(KeyboardKeys.F11);
|
public InputBinding DebuggerStepInto = new InputBinding(KeyboardKeys.F11);
|
||||||
|
|
||||||
[DefaultValue(typeof(InputBinding), "Shift+F11")]
|
[DefaultValue(typeof(InputBinding), "Shift+F11")]
|
||||||
[EditorDisplay("Debugger", "Step Out"), EditorOrder(840)]
|
[EditorDisplay("Debugger", "Step Out"), EditorOrder(850)]
|
||||||
public InputBinding DebuggerStepOut = new InputBinding(KeyboardKeys.F11, KeyboardKeys.Shift);
|
public InputBinding DebuggerStepOut = new InputBinding(KeyboardKeys.F11, KeyboardKeys.Shift);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@@ -208,15 +208,22 @@ namespace FlaxEditor.Options
|
|||||||
|
|
||||||
// If a non-default style was chosen, switch to that style
|
// If a non-default style was chosen, switch to that style
|
||||||
string styleName = themeOptions.SelectedStyle;
|
string styleName = themeOptions.SelectedStyle;
|
||||||
if (styleName != "Default" && themeOptions.Styles.TryGetValue(styleName, out var style) && style != null)
|
if (styleName != ThemeOptions.DefaultName && styleName != ThemeOptions.LightDefault && themeOptions.Styles.TryGetValue(styleName, out var style) && style != null)
|
||||||
{
|
{
|
||||||
Style.Current = style;
|
Style.Current = style;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if (styleName == ThemeOptions.LightDefault)
|
||||||
|
{
|
||||||
|
Style.Current = CreateLightStyle();
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
Style.Current = CreateDefaultStyle();
|
Style.Current = CreateDefaultStyle();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates the default style.
|
/// Creates the default style.
|
||||||
@@ -224,7 +231,6 @@ namespace FlaxEditor.Options
|
|||||||
/// <returns>The style object.</returns>
|
/// <returns>The style object.</returns>
|
||||||
public Style CreateDefaultStyle()
|
public Style CreateDefaultStyle()
|
||||||
{
|
{
|
||||||
// Metro Style colors
|
|
||||||
var options = Options;
|
var options = Options;
|
||||||
var style = new Style
|
var style = new Style
|
||||||
{
|
{
|
||||||
@@ -233,6 +239,7 @@ namespace FlaxEditor.Options
|
|||||||
Foreground = Color.FromBgra(0xFFFFFFFF),
|
Foreground = Color.FromBgra(0xFFFFFFFF),
|
||||||
ForegroundGrey = Color.FromBgra(0xFFA9A9B3),
|
ForegroundGrey = Color.FromBgra(0xFFA9A9B3),
|
||||||
ForegroundDisabled = Color.FromBgra(0xFF787883),
|
ForegroundDisabled = Color.FromBgra(0xFF787883),
|
||||||
|
ForegroundViewport = Color.FromBgra(0xFFFFFFFF),
|
||||||
BackgroundHighlighted = Color.FromBgra(0xFF54545C),
|
BackgroundHighlighted = Color.FromBgra(0xFF54545C),
|
||||||
BorderHighlighted = Color.FromBgra(0xFF6A6A75),
|
BorderHighlighted = Color.FromBgra(0xFF6A6A75),
|
||||||
BackgroundSelected = Color.FromBgra(0xFF007ACC),
|
BackgroundSelected = Color.FromBgra(0xFF007ACC),
|
||||||
@@ -274,7 +281,58 @@ namespace FlaxEditor.Options
|
|||||||
SharedTooltip = new Tooltip(),
|
SharedTooltip = new Tooltip(),
|
||||||
};
|
};
|
||||||
style.DragWindow = style.BackgroundSelected * 0.7f;
|
style.DragWindow = style.BackgroundSelected * 0.7f;
|
||||||
|
return style;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates the light style (2nd default).
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The style object.</returns>
|
||||||
|
public Style CreateLightStyle()
|
||||||
|
{
|
||||||
|
var options = Options;
|
||||||
|
var style = new Style
|
||||||
|
{
|
||||||
|
Background = new Color(0.92f, 0.92f, 0.92f, 1f),
|
||||||
|
LightBackground = new Color(0.84f, 0.84f, 0.88f, 1f),
|
||||||
|
DragWindow = new Color(0.0f, 0.26f, 0.43f, 0.70f),
|
||||||
|
Foreground = new Color(0.0f, 0.0f, 0.0f, 1f),
|
||||||
|
ForegroundGrey = new Color(0.30f, 0.30f, 0.31f, 1f),
|
||||||
|
ForegroundDisabled = new Color(0.45f, 0.45f, 0.49f, 1f),
|
||||||
|
ForegroundViewport = new Color(1.0f, 1.0f, 1.0f, 1f),
|
||||||
|
BackgroundHighlighted = new Color(0.59f, 0.59f, 0.64f, 1f),
|
||||||
|
BorderHighlighted = new Color(0.50f, 0.50f, 0.55f, 1f),
|
||||||
|
BackgroundSelected = new Color(0.00f, 0.46f, 0.78f, 0.78f),
|
||||||
|
BorderSelected = new Color(0.11f, 0.57f, 0.88f, 0.65f),
|
||||||
|
BackgroundNormal = new Color(0.67f, 0.67f, 0.75f, 1f),
|
||||||
|
BorderNormal = new Color(0.59f, 0.59f, 0.64f, 1f),
|
||||||
|
TextBoxBackground = new Color(0.75f, 0.75f, 0.81f, 1f),
|
||||||
|
TextBoxBackgroundSelected = new Color(0.73f, 0.73f, 0.80f, 1f),
|
||||||
|
CollectionBackgroundColor = new Color(0.85f, 0.85f, 0.88f, 1f),
|
||||||
|
ProgressNormal = new Color(0.03f, 0.65f, 0.12f, 1f),
|
||||||
|
|
||||||
|
// Fonts
|
||||||
|
FontTitle = options.Interface.TitleFont.GetFont(),
|
||||||
|
FontLarge = options.Interface.LargeFont.GetFont(),
|
||||||
|
FontMedium = options.Interface.MediumFont.GetFont(),
|
||||||
|
FontSmall = options.Interface.SmallFont.GetFont(),
|
||||||
|
|
||||||
|
// Icons
|
||||||
|
ArrowDown = Editor.Icons.ArrowDown12,
|
||||||
|
ArrowRight = Editor.Icons.ArrowRight12,
|
||||||
|
Search = Editor.Icons.Search12,
|
||||||
|
Settings = Editor.Icons.Settings12,
|
||||||
|
Cross = Editor.Icons.Cross12,
|
||||||
|
CheckBoxIntermediate = Editor.Icons.CheckBoxIntermediate12,
|
||||||
|
CheckBoxTick = Editor.Icons.CheckBoxTick12,
|
||||||
|
StatusBarSizeGrip = Editor.Icons.WindowDrag12,
|
||||||
|
Translate = Editor.Icons.Translate32,
|
||||||
|
Rotate = Editor.Icons.Rotate32,
|
||||||
|
Scale = Editor.Icons.Scale32,
|
||||||
|
Scalar = Editor.Icons.Scalar32,
|
||||||
|
|
||||||
|
SharedTooltip = new Tooltip(),
|
||||||
|
};
|
||||||
return style;
|
return style;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,9 @@ namespace FlaxEditor.Options
|
|||||||
[CustomEditor(typeof(ThemeOptionsEditor))]
|
[CustomEditor(typeof(ThemeOptionsEditor))]
|
||||||
public sealed class ThemeOptions
|
public sealed class ThemeOptions
|
||||||
{
|
{
|
||||||
|
internal const string DefaultName = "Default";
|
||||||
|
internal const string LightDefault = "LightDefault";
|
||||||
|
|
||||||
internal class ThemeOptionsEditor : Editor<ThemeOptions>
|
internal class ThemeOptionsEditor : Editor<ThemeOptions>
|
||||||
{
|
{
|
||||||
private LabelElement _infoLabel;
|
private LabelElement _infoLabel;
|
||||||
@@ -63,13 +66,14 @@ namespace FlaxEditor.Options
|
|||||||
private void ReloadOptions(ComboBox obj)
|
private void ReloadOptions(ComboBox obj)
|
||||||
{
|
{
|
||||||
var themeOptions = (ThemeOptions)ParentEditor.Values[0];
|
var themeOptions = (ThemeOptions)ParentEditor.Values[0];
|
||||||
var options = new string[themeOptions.Styles.Count + 1];
|
var options = new string[themeOptions.Styles.Count + 2];
|
||||||
options[0] = "Default";
|
options[0] = DefaultName;
|
||||||
|
options[1] = LightDefault;
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
foreach (var styleName in themeOptions.Styles.Keys)
|
foreach (var styleName in themeOptions.Styles.Keys)
|
||||||
{
|
{
|
||||||
options[i + 1] = styleName;
|
options[i + 2] = styleName;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
_combobox.ComboBox.SetItems(options);
|
_combobox.ComboBox.SetItems(options);
|
||||||
|
|||||||
@@ -26,45 +26,108 @@ namespace FlaxEditor.Options
|
|||||||
public float MouseWheelSensitivity { get; set; } = 1.0f;
|
public float MouseWheelSensitivity { get; set; } = 1.0f;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the default movement speed for the viewport camera (must match the dropdown menu values in the viewport).
|
/// Gets or sets the total amount of steps the camera needs to go from minimum to maximum speed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DefaultValue(1.0f), Limit(0.01f, 100.0f)]
|
[DefaultValue(64), Limit(1, 128)]
|
||||||
[EditorDisplay("Defaults"), EditorOrder(110), Tooltip("The default movement speed for the viewport camera (must match the dropdown menu values in the viewport).")]
|
[EditorDisplay("Camera"), EditorOrder(110), Tooltip("The total amount of steps the camera needs to go from minimum to maximum speed.")]
|
||||||
public float DefaultMovementSpeed { get; set; } = 1.0f;
|
public int TotalCameraSpeedSteps { get; set; } = 64;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the degree to which the camera will be eased when using camera flight in the editor window.
|
||||||
|
/// </summary>
|
||||||
|
[DefaultValue(3.0f), Limit(1.0f, 8.0f)]
|
||||||
|
[EditorDisplay("Camera"), EditorOrder(111), Tooltip("The degree to which the camera will be eased when using camera flight in the editor window (ignored if camera easing degree is enabled).")]
|
||||||
|
public float CameraEasingDegree { get; set; } = 3.0f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the default movement speed for the viewport camera (must be in range between minimum and maximum movement speed values).
|
||||||
|
/// </summary>
|
||||||
|
[DefaultValue(1.0f), Limit(0.05f, 32.0f)]
|
||||||
|
[EditorDisplay("Defaults"), EditorOrder(120), Tooltip("The default movement speed for the viewport camera (must be in range between minimum and maximum movement speed values).")]
|
||||||
|
public float MovementSpeed { get; set; } = 1.0f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the default minimum camera movement speed.
|
||||||
|
/// </summary>
|
||||||
|
[DefaultValue(0.05f), Limit(0.05f, 32.0f)]
|
||||||
|
[EditorDisplay("Defaults"), EditorOrder(121), Tooltip("The default minimum movement speed for the viewport camera.")]
|
||||||
|
public float MinMovementSpeed { get; set; } = 0.05f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the default maximum camera movement speed.
|
||||||
|
/// </summary>
|
||||||
|
[DefaultValue(32.0f), Limit(16.0f, 1000.0f)]
|
||||||
|
[EditorDisplay("Defaults"), EditorOrder(122), Tooltip("The default maximum movement speed for the viewport camera.")]
|
||||||
|
public float MaxMovementSpeed { get; set; } = 32f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the default camera easing mode.
|
||||||
|
/// </summary>
|
||||||
|
[DefaultValue(true)]
|
||||||
|
[EditorDisplay("Defaults"), EditorOrder(130), Tooltip("The default camera easing mode.")]
|
||||||
|
public bool UseCameraEasing { get; set; } = true;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the default near clipping plane distance for the viewport camera.
|
/// Gets or sets the default near clipping plane distance for the viewport camera.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DefaultValue(10.0f), Limit(0.001f, 1000.0f)]
|
[DefaultValue(10.0f), Limit(0.001f, 1000.0f)]
|
||||||
[EditorDisplay("Defaults"), EditorOrder(120), Tooltip("The default near clipping plane distance for the viewport camera.")]
|
[EditorDisplay("Defaults"), EditorOrder(140), Tooltip("The default near clipping plane distance for the viewport camera.")]
|
||||||
public float DefaultNearPlane { get; set; } = 10.0f;
|
public float NearPlane { get; set; } = 10.0f;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the default far clipping plane distance for the viewport camera.
|
/// Gets or sets the default far clipping plane distance for the viewport camera.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DefaultValue(40000.0f), Limit(10.0f)]
|
[DefaultValue(40000.0f), Limit(10.0f)]
|
||||||
[EditorDisplay("Defaults"), EditorOrder(130), Tooltip("The default far clipping plane distance for the viewport camera.")]
|
[EditorDisplay("Defaults"), EditorOrder(150), Tooltip("The default far clipping plane distance for the viewport camera.")]
|
||||||
public float DefaultFarPlane { get; set; } = 40000.0f;
|
public float FarPlane { get; set; } = 40000.0f;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the default field of view angle (in degrees) for the viewport camera.
|
/// Gets or sets the default field of view angle (in degrees) for the viewport camera.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DefaultValue(60.0f), Limit(35.0f, 160.0f, 0.1f)]
|
[DefaultValue(60.0f), Limit(35.0f, 160.0f, 0.1f)]
|
||||||
[EditorDisplay("Defaults", "Default Field Of View"), EditorOrder(140), Tooltip("The default field of view angle (in degrees) for the viewport camera.")]
|
[EditorDisplay("Defaults"), EditorOrder(160), Tooltip("The default field of view angle (in degrees) for the viewport camera.")]
|
||||||
public float DefaultFieldOfView { get; set; } = 60.0f;
|
public float FieldOfView { get; set; } = 60.0f;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets if the panning direction is inverted for the viewport camera.
|
/// Gets or sets the default camera orthographic mode.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DefaultValue(false)]
|
[DefaultValue(false)]
|
||||||
[EditorDisplay("Defaults"), EditorOrder(150), Tooltip("Invert the panning direction for the viewport camera.")]
|
[EditorDisplay("Defaults"), EditorOrder(170), Tooltip("The default camera orthographic mode.")]
|
||||||
public bool DefaultInvertPanning { get; set; } = false;
|
public bool UseOrthographicProjection { get; set; } = false;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Scales editor viewport grid.
|
/// Gets or sets the default camera orthographic scale (if camera uses orthographic mode).
|
||||||
|
/// </summary>
|
||||||
|
[DefaultValue(5.0f), Limit(0.001f, 100000.0f, 0.1f)]
|
||||||
|
[EditorDisplay("Defaults"), EditorOrder(180), Tooltip("The default camera orthographic scale (if camera uses orthographic mode).")]
|
||||||
|
public float OrthographicScale { get; set; } = 5.0f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the default panning direction for the viewport camera.
|
||||||
|
/// </summary>
|
||||||
|
[DefaultValue(false)]
|
||||||
|
[EditorDisplay("Defaults"), EditorOrder(190), Tooltip("The default panning direction for the viewport camera.")]
|
||||||
|
public bool InvertPanning { get; set; } = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the default relative panning mode.
|
||||||
|
/// </summary>
|
||||||
|
[DefaultValue(true)]
|
||||||
|
[EditorDisplay("Defaults"), EditorOrder(200), Tooltip("The default relative panning mode. Uses distance between camera and target to determine panning speed.")]
|
||||||
|
public bool UseRelativePanning { get; set; } = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the default panning speed (ignored if relative panning is speed enabled).
|
||||||
|
/// </summary>
|
||||||
|
[DefaultValue(0.8f), Limit(0.01f, 128.0f, 0.1f)]
|
||||||
|
[EditorDisplay("Defaults"), EditorOrder(210), Tooltip("The default camera panning speed (ignored if relative panning is enabled).")]
|
||||||
|
public float PanningSpeed { get; set; } = 0.8f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the default editor viewport grid scale.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DefaultValue(50.0f), Limit(25.0f, 500.0f, 5.0f)]
|
[DefaultValue(50.0f), Limit(25.0f, 500.0f, 5.0f)]
|
||||||
[EditorDisplay("Defaults"), EditorOrder(160), Tooltip("Scales editor viewport grid.")]
|
[EditorDisplay("Defaults"), EditorOrder(220), Tooltip("The default editor viewport grid scale.")]
|
||||||
public float ViewportGridScale { get; set; } = 50.0f;
|
public float ViewportGridScale { get; set; } = 50.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ namespace FlaxEditor.Progress.Handlers
|
|||||||
ScriptsBuilder.ScriptsReloadCalled += () => OnUpdate(0.8f, "Reloading scripts...");
|
ScriptsBuilder.ScriptsReloadCalled += () => OnUpdate(0.8f, "Reloading scripts...");
|
||||||
ScriptsBuilder.ScriptsReloadBegin += OnScriptsReloadBegin;
|
ScriptsBuilder.ScriptsReloadBegin += OnScriptsReloadBegin;
|
||||||
ScriptsBuilder.ScriptsReloadEnd += OnScriptsReloadEnd;
|
ScriptsBuilder.ScriptsReloadEnd += OnScriptsReloadEnd;
|
||||||
ScriptsBuilder.ScriptsReload += OnScriptsReload;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnScriptsReloadBegin()
|
private void OnScriptsReloadBegin()
|
||||||
@@ -38,14 +37,6 @@ namespace FlaxEditor.Progress.Handlers
|
|||||||
Editor.Instance.Scene.ClearRefsToSceneObjects(true);
|
Editor.Instance.Scene.ClearRefsToSceneObjects(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnScriptsReload()
|
|
||||||
{
|
|
||||||
#if !USE_NETCORE
|
|
||||||
// Clear types cache
|
|
||||||
Newtonsoft.Json.JsonSerializer.ClearCache();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnCompilationFailed()
|
private void OnCompilationFailed()
|
||||||
{
|
{
|
||||||
OnFail("Scripts compilation failed");
|
OnFail("Scripts compilation failed");
|
||||||
|
|||||||
@@ -154,7 +154,8 @@ bool ProjectInfo::LoadProject(const String& projectPath)
|
|||||||
Version = ::Version(
|
Version = ::Version(
|
||||||
JsonTools::GetInt(version, "Major", 0),
|
JsonTools::GetInt(version, "Major", 0),
|
||||||
JsonTools::GetInt(version, "Minor", 0),
|
JsonTools::GetInt(version, "Minor", 0),
|
||||||
JsonTools::GetInt(version, "Build", 0));
|
JsonTools::GetInt(version, "Build", -1),
|
||||||
|
JsonTools::GetInt(version, "Revision", -1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Version.Revision() == 0)
|
if (Version.Revision() == 0)
|
||||||
|
|||||||
@@ -23,18 +23,12 @@ namespace FlaxEditor
|
|||||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||||
{
|
{
|
||||||
if (value == null)
|
if (value == null)
|
||||||
{
|
|
||||||
writer.WriteNull();
|
writer.WriteNull();
|
||||||
}
|
|
||||||
else if (value is Version)
|
else if (value is Version)
|
||||||
{
|
|
||||||
writer.WriteValue(value.ToString());
|
writer.WriteValue(value.ToString());
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
throw new JsonSerializationException("Expected Version object value");
|
throw new JsonSerializationException("Expected Version object value");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reads the JSON representation of the object.
|
/// Reads the JSON representation of the object.
|
||||||
@@ -47,17 +41,14 @@ namespace FlaxEditor
|
|||||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||||
{
|
{
|
||||||
if (reader.TokenType == JsonToken.Null)
|
if (reader.TokenType == JsonToken.Null)
|
||||||
{
|
|
||||||
return null;
|
return null;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (reader.TokenType == JsonToken.StartObject)
|
if (reader.TokenType == JsonToken.StartObject)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
reader.Read();
|
reader.Read();
|
||||||
Dictionary<string, int> values = new Dictionary<string, int>();
|
var values = new Dictionary<string, int>();
|
||||||
while (reader.TokenType == JsonToken.PropertyName)
|
while (reader.TokenType == JsonToken.PropertyName)
|
||||||
{
|
{
|
||||||
var key = reader.Value as string;
|
var key = reader.Value as string;
|
||||||
@@ -67,45 +58,43 @@ namespace FlaxEditor
|
|||||||
values.Add(key, (int)val);
|
values.Add(key, (int)val);
|
||||||
}
|
}
|
||||||
|
|
||||||
int major = 0, minor = 0, build = 0;
|
values.TryGetValue("Major", out var major);
|
||||||
values.TryGetValue("Major", out major);
|
values.TryGetValue("Minor", out var minor);
|
||||||
values.TryGetValue("Minor", out minor);
|
if (!values.TryGetValue("Build", out var build))
|
||||||
values.TryGetValue("Build", out build);
|
build = -1;
|
||||||
|
if (!values.TryGetValue("Revision", out var revision))
|
||||||
|
revision = -1;
|
||||||
|
|
||||||
Version v = new Version(major, minor, build);
|
if (build <= 0)
|
||||||
return v;
|
return new Version(major, minor);
|
||||||
|
if (revision <= 0)
|
||||||
|
return new Version(major, minor, build);
|
||||||
|
return new Version(major, minor, build, revision);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
throw new Exception(String.Format("Error parsing version string: {0}", reader.Value), ex);
|
throw new Exception(String.Format("Error parsing version string: {0}", reader.Value), ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (reader.TokenType == JsonToken.String)
|
if (reader.TokenType == JsonToken.String)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Version v = new Version((string)reader.Value!);
|
return new Version((string)reader.Value!);
|
||||||
return v;
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
throw new Exception(String.Format("Error parsing version string: {0}", reader.Value), ex);
|
throw new Exception(String.Format("Error parsing version string: {0}", reader.Value), ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new Exception(String.Format("Unexpected token or value when parsing version. Token: {0}, Value: {1}", reader.TokenType, reader.Value));
|
throw new Exception(String.Format("Unexpected token or value when parsing version. Token: {0}, Value: {1}", reader.TokenType, reader.Value));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines whether this instance can convert the specified object type.
|
/// Determines whether this instance can convert the specified object type.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="objectType">Type of the object.</param>
|
/// <param name="objectType">Type of the object.</param>
|
||||||
/// <returns>
|
/// <returns><c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.</returns>
|
||||||
/// <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
|
|
||||||
/// </returns>
|
|
||||||
public override bool CanConvert(Type objectType)
|
public override bool CanConvert(Type objectType)
|
||||||
{
|
{
|
||||||
return objectType == typeof(Version);
|
return objectType == typeof(Version);
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ using Real = System.Single;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
using FlaxEngine;
|
using FlaxEngine;
|
||||||
|
using FlaxEngine.GUI;
|
||||||
|
|
||||||
namespace FlaxEditor.SceneGraph.Actors
|
namespace FlaxEditor.SceneGraph.Actors
|
||||||
{
|
{
|
||||||
@@ -30,6 +31,13 @@ namespace FlaxEditor.SceneGraph.Actors
|
|||||||
|
|
||||||
// Rotate to match the space (GUI uses upper left corner as a root)
|
// Rotate to match the space (GUI uses upper left corner as a root)
|
||||||
Actor.LocalOrientation = Quaternion.Euler(0, -180, -180);
|
Actor.LocalOrientation = Quaternion.Euler(0, -180, -180);
|
||||||
|
var uiControl = new UIControl
|
||||||
|
{
|
||||||
|
Name = "Canvas Scalar",
|
||||||
|
Transform = Actor.Transform,
|
||||||
|
Control = new CanvasScaler()
|
||||||
|
};
|
||||||
|
Root.Spawn(uiControl, Actor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|||||||
@@ -66,7 +66,8 @@ namespace FlaxEditor.SceneGraph.GUI
|
|||||||
_orderInParent = actor.OrderInParent;
|
_orderInParent = actor.OrderInParent;
|
||||||
Visible = (actor.HideFlags & HideFlags.HideInHierarchy) == 0;
|
Visible = (actor.HideFlags & HideFlags.HideInHierarchy) == 0;
|
||||||
|
|
||||||
var id = actor.ID;
|
// Pick the correct id when inside a prefab window.
|
||||||
|
var id = actor.HasPrefabLink && actor.Scene == null ? actor.PrefabObjectID : actor.ID;
|
||||||
if (Editor.Instance.ProjectCache.IsExpandedActor(ref id))
|
if (Editor.Instance.ProjectCache.IsExpandedActor(ref id))
|
||||||
{
|
{
|
||||||
Expand(true);
|
Expand(true);
|
||||||
@@ -171,7 +172,8 @@ namespace FlaxEditor.SceneGraph.GUI
|
|||||||
// Restore cached state on query filter clear
|
// Restore cached state on query filter clear
|
||||||
if (noFilter && actor != null)
|
if (noFilter && actor != null)
|
||||||
{
|
{
|
||||||
var id = actor.ID;
|
// Pick the correct id when inside a prefab window.
|
||||||
|
var id = actor.HasPrefabLink && actor.Scene.Scene == null ? actor.PrefabObjectID : actor.ID;
|
||||||
isExpanded = Editor.Instance.ProjectCache.IsExpandedActor(ref id);
|
isExpanded = Editor.Instance.ProjectCache.IsExpandedActor(ref id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -264,7 +266,7 @@ namespace FlaxEditor.SceneGraph.GUI
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Starts the actor renaming action.
|
/// Starts the actor renaming action.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void StartRenaming(EditorWindow window)
|
public void StartRenaming(EditorWindow window, Panel treePanel = null)
|
||||||
{
|
{
|
||||||
// Block renaming during scripts reload
|
// Block renaming during scripts reload
|
||||||
if (Editor.Instance.ProgressReporting.CompileScripts.IsActive)
|
if (Editor.Instance.ProgressReporting.CompileScripts.IsActive)
|
||||||
@@ -279,7 +281,13 @@ namespace FlaxEditor.SceneGraph.GUI
|
|||||||
(window as PrefabWindow).ScrollingOnTreeView(false);
|
(window as PrefabWindow).ScrollingOnTreeView(false);
|
||||||
|
|
||||||
// Start renaming the actor
|
// Start renaming the actor
|
||||||
var dialog = RenamePopup.Show(this, TextRect, _actorNode.Name, false);
|
var rect = TextRect;
|
||||||
|
if (treePanel != null)
|
||||||
|
{
|
||||||
|
treePanel.ScrollViewTo(this, true);
|
||||||
|
rect.Size = new Float2(treePanel.Width - TextRect.Location.X, TextRect.Height);
|
||||||
|
}
|
||||||
|
var dialog = RenamePopup.Show(this, rect, _actorNode.Name, false);
|
||||||
dialog.Renamed += OnRenamed;
|
dialog.Renamed += OnRenamed;
|
||||||
dialog.Closed += popup =>
|
dialog.Closed += popup =>
|
||||||
{
|
{
|
||||||
@@ -301,10 +309,12 @@ namespace FlaxEditor.SceneGraph.GUI
|
|||||||
protected override void OnExpandedChanged()
|
protected override void OnExpandedChanged()
|
||||||
{
|
{
|
||||||
base.OnExpandedChanged();
|
base.OnExpandedChanged();
|
||||||
|
var actor = Actor;
|
||||||
|
|
||||||
if (!IsLayoutLocked && Actor)
|
if (!IsLayoutLocked && actor)
|
||||||
{
|
{
|
||||||
var id = Actor.ID;
|
// Pick the correct id when inside a prefab window.
|
||||||
|
var id = actor.HasPrefabLink && actor.Scene == null ? actor.PrefabObjectID : actor.ID;
|
||||||
Editor.Instance.ProjectCache.SetExpandedActor(ref id, IsExpanded);
|
Editor.Instance.ProjectCache.SetExpandedActor(ref id, IsExpanded);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -207,9 +207,9 @@ void RiderCodeEditor::FindEditors(Array<CodeEditor*>* output)
|
|||||||
FileSystem::GetChildDirectories(subDirectories, TEXT("/opt/"));
|
FileSystem::GetChildDirectories(subDirectories, TEXT("/opt/"));
|
||||||
|
|
||||||
// Versions installed via JetBrains Toolbox
|
// Versions installed via JetBrains Toolbox
|
||||||
SearchDirectory(&installations, localAppDataPath / TEXT(".local/share/JetBrains/Toolbox/apps/rider/"));
|
SearchDirectory(&installations, localAppDataPath / TEXT("JetBrains/Toolbox/apps/rider/"));
|
||||||
FileSystem::GetChildDirectories(subDirectories, localAppDataPath / TEXT(".local/share/JetBrains/Toolbox/apps/Rider/ch-0"));
|
FileSystem::GetChildDirectories(subDirectories, localAppDataPath / TEXT("JetBrains/Toolbox/apps/Rider/ch-0"));
|
||||||
FileSystem::GetChildDirectories(subDirectories, localAppDataPath / TEXT(".local/share/JetBrains/Toolbox/apps/Rider/ch-1")); // Beta versions
|
FileSystem::GetChildDirectories(subDirectories, localAppDataPath / TEXT("JetBrains/Toolbox/apps/Rider/ch-1")); // Beta versions
|
||||||
|
|
||||||
// Detect Flatpak installations
|
// Detect Flatpak installations
|
||||||
SearchDirectory(&installations,
|
SearchDirectory(&installations,
|
||||||
|
|||||||
@@ -78,7 +78,10 @@ void VisualStudioCodeEditor::FindEditors(Array<CodeEditor*>* output)
|
|||||||
|
|
||||||
// Detect Flatpak installations
|
// Detect Flatpak installations
|
||||||
{
|
{
|
||||||
if (Platform::RunProcess(TEXT("/bin/bash -c \"flatpak list --app --columns=application | grep com.visualstudio.code -c\""), String::Empty) == 0)
|
CreateProcessSettings procSettings;
|
||||||
|
procSettings.FileName = TEXT("/bin/bash -c \"flatpak list --app --columns=application | grep com.visualstudio.code -c\"");
|
||||||
|
procSettings.HiddenWindow = true;
|
||||||
|
if (Platform::CreateProcess(procSettings) == 0)
|
||||||
{
|
{
|
||||||
const String runPath(TEXT("flatpak run com.visualstudio.code"));
|
const String runPath(TEXT("flatpak run com.visualstudio.code"));
|
||||||
output->Add(New<VisualStudioCodeEditor>(runPath, false));
|
output->Add(New<VisualStudioCodeEditor>(runPath, false));
|
||||||
|
|||||||
@@ -56,12 +56,14 @@ namespace FlaxEditor.States
|
|||||||
else if (Editor.Options.Options.General.ForceScriptCompilationOnStartup && !skipCompile)
|
else if (Editor.Options.Options.General.ForceScriptCompilationOnStartup && !skipCompile)
|
||||||
{
|
{
|
||||||
// Generate project files when Cache is missing or was cleared previously
|
// Generate project files when Cache is missing or was cleared previously
|
||||||
if (!Directory.Exists(Path.Combine(Editor.GameProject?.ProjectFolderPath, "Cache", "Intermediate")) ||
|
var projectFolderPath = Editor.GameProject?.ProjectFolderPath;
|
||||||
!Directory.Exists(Path.Combine(Editor.GameProject?.ProjectFolderPath, "Cache", "Projects")))
|
if (!Directory.Exists(Path.Combine(projectFolderPath, "Cache", "Intermediate")) ||
|
||||||
|
!Directory.Exists(Path.Combine(projectFolderPath, "Cache", "Projects")))
|
||||||
{
|
{
|
||||||
var customArgs = Editor.Instance.CodeEditing.SelectedEditor.GenerateProjectCustomArgs;
|
var customArgs = Editor.CodeEditing.SelectedEditor?.GenerateProjectCustomArgs;
|
||||||
ScriptsBuilder.GenerateProject(customArgs);
|
ScriptsBuilder.GenerateProject(customArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compile scripts before loading any scenes, then we load them and can open scenes
|
// Compile scripts before loading any scenes, then we load them and can open scenes
|
||||||
ScriptsBuilder.Compile();
|
ScriptsBuilder.Compile();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
|
// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
|
||||||
|
|
||||||
using FlaxEngine;
|
using FlaxEngine;
|
||||||
using FlaxEditor.Utilities;
|
|
||||||
using FlaxEngine.Utilities;
|
using FlaxEngine.Utilities;
|
||||||
|
|
||||||
namespace FlaxEditor.States
|
namespace FlaxEditor.States
|
||||||
|
|||||||
@@ -465,7 +465,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
if (selectedIndex != -1)
|
if (selectedIndex != -1)
|
||||||
{
|
{
|
||||||
var index = 5 + selectedIndex * 2;
|
var index = 5 + selectedIndex * 2;
|
||||||
SetValue(index, _animationPicker.SelectedID);
|
SetValue(index, _animationPicker.Validator.SelectedID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -495,7 +495,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
{
|
{
|
||||||
if (isValid)
|
if (isValid)
|
||||||
{
|
{
|
||||||
_animationPicker.SelectedID = data1;
|
_animationPicker.Validator.SelectedID = data1;
|
||||||
_animationSpeed.Value = data0.W;
|
_animationSpeed.Value = data0.W;
|
||||||
|
|
||||||
var path = string.Empty;
|
var path = string.Empty;
|
||||||
@@ -505,7 +505,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_animationPicker.SelectedID = Guid.Empty;
|
_animationPicker.Validator.SelectedID = Guid.Empty;
|
||||||
_animationSpeed.Value = 1.0f;
|
_animationSpeed.Value = 1.0f;
|
||||||
}
|
}
|
||||||
_animationPicker.Enabled = isValid;
|
_animationPicker.Enabled = isValid;
|
||||||
|
|||||||
@@ -288,6 +288,9 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
SetValue(2, ids);
|
SetValue(2, ids);
|
||||||
|
|
||||||
|
// Force refresh UI
|
||||||
|
ResizeAuto();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
Op1(1, "Bitwise NOT", "Negates the value using bitwise operation", new[] { "!", "~" }),
|
Op1(1, "Bitwise NOT", "Negates the value using bitwise operation", new[] { "!", "~" }),
|
||||||
Op2(2, "Bitwise AND", "Performs a bitwise conjunction on two values", new[] { "&" }),
|
Op2(2, "Bitwise AND", "Performs a bitwise conjunction on two values", new[] { "&" }),
|
||||||
Op2(3, "Bitwise OR", "", new[] { "|" }),
|
Op2(3, "Bitwise OR", "", new[] { "|" }),
|
||||||
Op2(4, "Bitwise XOR", ""),
|
Op2(4, "Bitwise XOR", "", new[] { "^" }),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
Op1(1, "Boolean NOT", "Negates the boolean value", new[] { "!", "~" }),
|
Op1(1, "Boolean NOT", "Negates the boolean value", new[] { "!", "~" }),
|
||||||
Op2(2, "Boolean AND", "Performs a logical conjunction on two values", new[] { "&&" }),
|
Op2(2, "Boolean AND", "Performs a logical conjunction on two values", new[] { "&&" }),
|
||||||
Op2(3, "Boolean OR", "Returns true if either (or both) of its operands is true", new[] { "||" }),
|
Op2(3, "Boolean OR", "Returns true if either (or both) of its operands is true", new[] { "||" }),
|
||||||
Op2(4, "Boolean XOR", ""),
|
Op2(4, "Boolean XOR", "", new [] { "^" } ),
|
||||||
Op2(5, "Boolean NOR", ""),
|
Op2(5, "Boolean NOR", ""),
|
||||||
Op2(6, "Boolean NAND", ""),
|
Op2(6, "Boolean NAND", ""),
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
[HideInEditor]
|
[HideInEditor]
|
||||||
public static class Comparisons
|
public static class Comparisons
|
||||||
{
|
{
|
||||||
private static NodeArchetype Op(ushort id, string title, string desc)
|
private static NodeArchetype Op(ushort id, string title, string desc, string[] altTitles = null)
|
||||||
{
|
{
|
||||||
return new NodeArchetype
|
return new NodeArchetype
|
||||||
{
|
{
|
||||||
@@ -22,6 +22,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
Title = title,
|
Title = title,
|
||||||
Description = desc,
|
Description = desc,
|
||||||
Flags = NodeFlags.AllGraphs,
|
Flags = NodeFlags.AllGraphs,
|
||||||
|
AlternativeTitles = altTitles,
|
||||||
ConnectionsHints = ConnectionsHint.Value,
|
ConnectionsHints = ConnectionsHint.Value,
|
||||||
Size = new Float2(100, 40),
|
Size = new Float2(100, 40),
|
||||||
IndependentBoxes = new[]
|
IndependentBoxes = new[]
|
||||||
@@ -170,12 +171,12 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static NodeArchetype[] Nodes =
|
public static NodeArchetype[] Nodes =
|
||||||
{
|
{
|
||||||
Op(1, "==", "Determines whether two values are equal"),
|
Op(1, "==", "Determines whether two values are equal", new[] { "equals" }),
|
||||||
Op(2, "!=", "Determines whether two values are not equal"),
|
Op(2, "!=", "Determines whether two values are not equal", new[] { "not equals" }),
|
||||||
Op(3, ">", "Determines whether the first value is greater than the other"),
|
Op(3, ">", "Determines whether the first value is greater than the other", new[] { "greater than", "larger than", "bigger than" }),
|
||||||
Op(4, "<", "Determines whether the first value is less than the other"),
|
Op(4, "<", "Determines whether the first value is less than the other", new[] { "less than", "smaller than" }),
|
||||||
Op(5, "<=", "Determines whether the first value is less or equal to the other"),
|
Op(5, "<=", "Determines whether the first value is less or equal to the other", new[] { "less equals than", "smaller equals than" }),
|
||||||
Op(6, ">=", "Determines whether the first value is greater or equal to the other"),
|
Op(6, ">=", "Determines whether the first value is greater or equal to the other", new[] { "greater equals than", "larger equals than", "bigger equals than" }),
|
||||||
new NodeArchetype
|
new NodeArchetype
|
||||||
{
|
{
|
||||||
TypeID = 7,
|
TypeID = 7,
|
||||||
|
|||||||
@@ -7,11 +7,12 @@ using Real = System.Single;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Reflection;
|
using System.Linq;
|
||||||
using FlaxEditor.CustomEditors.Editors;
|
using FlaxEditor.CustomEditors.Editors;
|
||||||
using FlaxEditor.GUI;
|
using FlaxEditor.GUI;
|
||||||
using FlaxEditor.Scripting;
|
using FlaxEditor.Scripting;
|
||||||
using FlaxEditor.Surface.Elements;
|
using FlaxEditor.Surface.Elements;
|
||||||
|
using FlaxEditor.Surface.Undo;
|
||||||
using FlaxEngine;
|
using FlaxEngine;
|
||||||
using FlaxEngine.GUI;
|
using FlaxEngine.GUI;
|
||||||
using FlaxEngine.Utilities;
|
using FlaxEngine.Utilities;
|
||||||
@@ -24,6 +25,109 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
[HideInEditor]
|
[HideInEditor]
|
||||||
public static class Constants
|
public static class Constants
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A special type of node that adds the functionality to convert nodes to parameters.
|
||||||
|
/// </summary>
|
||||||
|
internal class ConvertToParameterNode : SurfaceNode
|
||||||
|
{
|
||||||
|
private readonly ScriptType _type;
|
||||||
|
private readonly Func<object[], object> _convertFunction;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public ConvertToParameterNode(uint id, VisjectSurfaceContext context, NodeArchetype nodeArch, GroupArchetype groupArch, ScriptType type, Func<object[], object> convertFunction = null)
|
||||||
|
: base(id, context, nodeArch, groupArch)
|
||||||
|
{
|
||||||
|
_type = type;
|
||||||
|
_convertFunction = convertFunction;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnShowSecondaryContextMenu(FlaxEditor.GUI.ContextMenu.ContextMenu menu, Float2 location)
|
||||||
|
{
|
||||||
|
base.OnShowSecondaryContextMenu(menu, location);
|
||||||
|
|
||||||
|
menu.AddSeparator();
|
||||||
|
menu.AddButton("Convert to Parameter", OnConvertToParameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnConvertToParameter()
|
||||||
|
{
|
||||||
|
if (Surface.Owner is not IVisjectSurfaceWindow window)
|
||||||
|
throw new Exception("Surface owner is not a Visject Surface Window");
|
||||||
|
|
||||||
|
Asset asset = Surface.Owner.SurfaceAsset;
|
||||||
|
if (asset == null || !asset.IsLoaded)
|
||||||
|
{
|
||||||
|
Editor.LogError("Asset is null or not loaded");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add parameter to editor
|
||||||
|
var paramIndex = Surface.Parameters.Count;
|
||||||
|
var initValue = _convertFunction == null ? Values[0] : _convertFunction.Invoke(Values);
|
||||||
|
var paramAction = new AddRemoveParamAction
|
||||||
|
{
|
||||||
|
Window = window,
|
||||||
|
IsAdd = true,
|
||||||
|
Name = Utilities.Utils.IncrementNameNumber("New parameter", OnParameterRenameValidate),
|
||||||
|
Type = _type,
|
||||||
|
Index = paramIndex,
|
||||||
|
InitValue = initValue,
|
||||||
|
};
|
||||||
|
paramAction.Do();
|
||||||
|
Surface.AddBatchedUndoAction(paramAction);
|
||||||
|
|
||||||
|
// Spawn Get Parameter Node based on the added parameter
|
||||||
|
Guid parameterGuid = Surface.Parameters[paramIndex].ID;
|
||||||
|
bool undoEnabled = Surface.Undo.Enabled;
|
||||||
|
Surface.Undo.Enabled = false;
|
||||||
|
NodeArchetype arch = Surface.GetParameterGetterNodeArchetype(out var groupId);
|
||||||
|
SurfaceNode node = Surface.Context.SpawnNode(groupId, arch.TypeID, Location, new object[] { parameterGuid });
|
||||||
|
Surface.Undo.Enabled = undoEnabled;
|
||||||
|
if (node is not Parameters.SurfaceNodeParamsGet getNode)
|
||||||
|
throw new Exception("Node is not a ParamsGet node!");
|
||||||
|
Surface.AddBatchedUndoAction(new AddRemoveNodeAction(getNode, true));
|
||||||
|
|
||||||
|
// Recreate connections of constant node
|
||||||
|
// Constant nodes and parameter nodes should have the same ports, so we can just iterate through the connections
|
||||||
|
var editConnectionsAction1 = new EditNodeConnections(Context, this);
|
||||||
|
var editConnectionsAction2 = new EditNodeConnections(Context, node);
|
||||||
|
var boxes = GetBoxes();
|
||||||
|
for (int i = 0; i < boxes.Count; i++)
|
||||||
|
{
|
||||||
|
Box box = boxes[i];
|
||||||
|
if (!box.HasAnyConnection)
|
||||||
|
continue;
|
||||||
|
if (!getNode.TryGetBox(box.ID, out Box paramBox))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Iterating backwards, because the CreateConnection method deletes entries from the box connections when target box IsSingle is set to true
|
||||||
|
for (int k = box.Connections.Count - 1; k >= 0; k--)
|
||||||
|
{
|
||||||
|
Box connectedBox = box.Connections[k];
|
||||||
|
paramBox.CreateConnection(connectedBox);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
editConnectionsAction1.End();
|
||||||
|
editConnectionsAction2.End();
|
||||||
|
Surface.AddBatchedUndoAction(editConnectionsAction1);
|
||||||
|
Surface.AddBatchedUndoAction(editConnectionsAction2);
|
||||||
|
|
||||||
|
// Add undo actions and remove constant node
|
||||||
|
var removeConstantAction = new AddRemoveNodeAction(this, false);
|
||||||
|
Surface.AddBatchedUndoAction(removeConstantAction);
|
||||||
|
removeConstantAction.Do();
|
||||||
|
Surface.MarkAsEdited();
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool OnParameterRenameValidate(string value)
|
||||||
|
{
|
||||||
|
if (Surface.Owner is not IVisjectSurfaceWindow window)
|
||||||
|
throw new Exception("Surface owner is not a Visject Surface Window");
|
||||||
|
return !string.IsNullOrWhiteSpace(value) && window.VisjectSurface.Parameters.All(x => x.Name != value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private class EnumNode : SurfaceNode
|
private class EnumNode : SurfaceNode
|
||||||
{
|
{
|
||||||
private EnumComboBox _picker;
|
private EnumComboBox _picker;
|
||||||
@@ -356,6 +460,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
{
|
{
|
||||||
TypeID = 1,
|
TypeID = 1,
|
||||||
Title = "Bool",
|
Title = "Bool",
|
||||||
|
Create = (id, context, arch, groupArch) => new ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(bool))),
|
||||||
Description = "Constant boolean value",
|
Description = "Constant boolean value",
|
||||||
Flags = NodeFlags.AllGraphs,
|
Flags = NodeFlags.AllGraphs,
|
||||||
Size = new Float2(110, 20),
|
Size = new Float2(110, 20),
|
||||||
@@ -388,6 +493,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
{
|
{
|
||||||
TypeID = 2,
|
TypeID = 2,
|
||||||
Title = "Integer",
|
Title = "Integer",
|
||||||
|
Create = (id, context, arch, groupArch) => new ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(int))),
|
||||||
Description = "Constant integer value",
|
Description = "Constant integer value",
|
||||||
Flags = NodeFlags.AllGraphs,
|
Flags = NodeFlags.AllGraphs,
|
||||||
Size = new Float2(110, 20),
|
Size = new Float2(110, 20),
|
||||||
@@ -415,6 +521,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
{
|
{
|
||||||
TypeID = 3,
|
TypeID = 3,
|
||||||
Title = "Float",
|
Title = "Float",
|
||||||
|
Create = (id, context, arch, groupArch) => new ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(float))),
|
||||||
Description = "Constant floating point",
|
Description = "Constant floating point",
|
||||||
Flags = NodeFlags.AllGraphs,
|
Flags = NodeFlags.AllGraphs,
|
||||||
Size = new Float2(110, 20),
|
Size = new Float2(110, 20),
|
||||||
@@ -442,6 +549,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
{
|
{
|
||||||
TypeID = 4,
|
TypeID = 4,
|
||||||
Title = "Float2",
|
Title = "Float2",
|
||||||
|
Create = (id, context, arch, groupArch) => new ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(Float2))),
|
||||||
Description = "Constant Float2",
|
Description = "Constant Float2",
|
||||||
Flags = NodeFlags.AllGraphs,
|
Flags = NodeFlags.AllGraphs,
|
||||||
Size = new Float2(130, 60),
|
Size = new Float2(130, 60),
|
||||||
@@ -472,6 +580,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
{
|
{
|
||||||
TypeID = 5,
|
TypeID = 5,
|
||||||
Title = "Float3",
|
Title = "Float3",
|
||||||
|
Create = (id, context, arch, groupArch) => new ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(Float3))),
|
||||||
Description = "Constant Float3",
|
Description = "Constant Float3",
|
||||||
Flags = NodeFlags.AllGraphs,
|
Flags = NodeFlags.AllGraphs,
|
||||||
Size = new Float2(130, 80),
|
Size = new Float2(130, 80),
|
||||||
@@ -504,6 +613,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
{
|
{
|
||||||
TypeID = 6,
|
TypeID = 6,
|
||||||
Title = "Float4",
|
Title = "Float4",
|
||||||
|
Create = (id, context, arch, groupArch) => new ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(Float4))),
|
||||||
Description = "Constant Float4",
|
Description = "Constant Float4",
|
||||||
Flags = NodeFlags.AllGraphs,
|
Flags = NodeFlags.AllGraphs,
|
||||||
Size = new Float2(130, 100),
|
Size = new Float2(130, 100),
|
||||||
@@ -538,6 +648,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
{
|
{
|
||||||
TypeID = 7,
|
TypeID = 7,
|
||||||
Title = "Color",
|
Title = "Color",
|
||||||
|
Create = (id, context, arch, groupArch) => new ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(Color))),
|
||||||
Description = "RGBA color",
|
Description = "RGBA color",
|
||||||
Flags = NodeFlags.AllGraphs,
|
Flags = NodeFlags.AllGraphs,
|
||||||
Size = new Float2(70, 100),
|
Size = new Float2(70, 100),
|
||||||
@@ -570,6 +681,8 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
{
|
{
|
||||||
TypeID = 8,
|
TypeID = 8,
|
||||||
Title = "Rotation",
|
Title = "Rotation",
|
||||||
|
Create = (id, context, arch, groupArch) =>
|
||||||
|
new ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(Quaternion)), values => Quaternion.Euler((float)values[0], (float)values[1], (float)values[2])),
|
||||||
Description = "Euler angle rotation",
|
Description = "Euler angle rotation",
|
||||||
Flags = NodeFlags.AnimGraph | NodeFlags.VisualScriptGraph | NodeFlags.ParticleEmitterGraph,
|
Flags = NodeFlags.AnimGraph | NodeFlags.VisualScriptGraph | NodeFlags.ParticleEmitterGraph,
|
||||||
Size = new Float2(110, 60),
|
Size = new Float2(110, 60),
|
||||||
@@ -594,6 +707,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
{
|
{
|
||||||
TypeID = 9,
|
TypeID = 9,
|
||||||
Title = "String",
|
Title = "String",
|
||||||
|
Create = (id, context, arch, groupArch) => new ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(string))),
|
||||||
Description = "Text",
|
Description = "Text",
|
||||||
Flags = NodeFlags.VisualScriptGraph | NodeFlags.AnimGraph,
|
Flags = NodeFlags.VisualScriptGraph | NodeFlags.AnimGraph,
|
||||||
Size = new Float2(200, 20),
|
Size = new Float2(200, 20),
|
||||||
@@ -644,6 +758,8 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
{
|
{
|
||||||
TypeID = 12,
|
TypeID = 12,
|
||||||
Title = "Unsigned Integer",
|
Title = "Unsigned Integer",
|
||||||
|
AlternativeTitles = new[] { "UInt", "U Int" },
|
||||||
|
Create = (id, context, arch, groupArch) => new ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(uint))),
|
||||||
Description = "Constant unsigned integer value",
|
Description = "Constant unsigned integer value",
|
||||||
Flags = NodeFlags.AllGraphs,
|
Flags = NodeFlags.AllGraphs,
|
||||||
Size = new Float2(170, 20),
|
Size = new Float2(170, 20),
|
||||||
@@ -683,6 +799,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
{
|
{
|
||||||
TypeID = 15,
|
TypeID = 15,
|
||||||
Title = "Double",
|
Title = "Double",
|
||||||
|
Create = (id, context, arch, groupArch) => new ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(double))),
|
||||||
Description = "Constant floating point",
|
Description = "Constant floating point",
|
||||||
Flags = NodeFlags.AllGraphs,
|
Flags = NodeFlags.AllGraphs,
|
||||||
Size = new Float2(110, 20),
|
Size = new Float2(110, 20),
|
||||||
@@ -700,6 +817,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
{
|
{
|
||||||
TypeID = 16,
|
TypeID = 16,
|
||||||
Title = "Vector2",
|
Title = "Vector2",
|
||||||
|
Create = (id, context, arch, groupArch) => new ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(Vector2))),
|
||||||
Description = "Constant Vector2",
|
Description = "Constant Vector2",
|
||||||
Flags = NodeFlags.AllGraphs,
|
Flags = NodeFlags.AllGraphs,
|
||||||
Size = new Float2(130, 60),
|
Size = new Float2(130, 60),
|
||||||
@@ -720,6 +838,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
{
|
{
|
||||||
TypeID = 17,
|
TypeID = 17,
|
||||||
Title = "Vector3",
|
Title = "Vector3",
|
||||||
|
Create = (id, context, arch, groupArch) => new ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(Vector3))),
|
||||||
Description = "Constant Vector3",
|
Description = "Constant Vector3",
|
||||||
Flags = NodeFlags.AllGraphs,
|
Flags = NodeFlags.AllGraphs,
|
||||||
Size = new Float2(130, 80),
|
Size = new Float2(130, 80),
|
||||||
@@ -742,6 +861,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
{
|
{
|
||||||
TypeID = 18,
|
TypeID = 18,
|
||||||
Title = "Vector4",
|
Title = "Vector4",
|
||||||
|
Create = (id, context, arch, groupArch) => new ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(Vector4))),
|
||||||
Description = "Constant Vector4",
|
Description = "Constant Vector4",
|
||||||
Flags = NodeFlags.AllGraphs,
|
Flags = NodeFlags.AllGraphs,
|
||||||
Size = new Float2(130, 100),
|
Size = new Float2(130, 100),
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
|
|
||||||
private void OnAssetPickerSelectedItemChanged()
|
private void OnAssetPickerSelectedItemChanged()
|
||||||
{
|
{
|
||||||
SetValue(0, _assetPicker.SelectedID);
|
SetValue(0, _assetPicker.Validator.SelectedID);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TryRestoreConnections(Box box, Box[] prevBoxes, ref NodeElementArchetype arch)
|
private void TryRestoreConnections(Box box, Box[] prevBoxes, ref NodeElementArchetype arch)
|
||||||
@@ -133,7 +133,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
var prevOutputs = _outputs;
|
var prevOutputs = _outputs;
|
||||||
|
|
||||||
// Extract function signature parameters (inputs and outputs packed)
|
// Extract function signature parameters (inputs and outputs packed)
|
||||||
_asset = LoadSignature(_assetPicker.SelectedID, out var typeNames, out var names);
|
_asset = LoadSignature(_assetPicker.Validator.SelectedID, out var typeNames, out var names);
|
||||||
if (typeNames != null && names != null)
|
if (typeNames != null && names != null)
|
||||||
{
|
{
|
||||||
var types = new Type[typeNames.Length];
|
var types = new Type[typeNames.Length];
|
||||||
@@ -174,7 +174,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
_outputs[i] = box;
|
_outputs[i] = box;
|
||||||
}
|
}
|
||||||
|
|
||||||
Title = _assetPicker.SelectedItem.ShortName;
|
Title = _assetPicker.Validator.SelectedItem.ShortName;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -2470,6 +2470,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
Title = string.Empty,
|
Title = string.Empty,
|
||||||
Description = "Overrides the base class method with custom implementation",
|
Description = "Overrides the base class method with custom implementation",
|
||||||
Flags = NodeFlags.VisualScriptGraph | NodeFlags.NoSpawnViaGUI | NodeFlags.NoSpawnViaPaste,
|
Flags = NodeFlags.VisualScriptGraph | NodeFlags.NoSpawnViaGUI | NodeFlags.NoSpawnViaPaste,
|
||||||
|
SortScore = 10,
|
||||||
IsInputCompatible = MethodOverrideNode.IsInputCompatible,
|
IsInputCompatible = MethodOverrideNode.IsInputCompatible,
|
||||||
IsOutputCompatible = MethodOverrideNode.IsOutputCompatible,
|
IsOutputCompatible = MethodOverrideNode.IsOutputCompatible,
|
||||||
Size = new Float2(240, 60),
|
Size = new Float2(240, 60),
|
||||||
|
|||||||
@@ -882,6 +882,60 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
NodeElementArchetype.Factory.Output(1, "Inv Size", typeof(Float2), 1),
|
NodeElementArchetype.Factory.Output(1, "Inv Size", typeof(Float2), 1),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
new NodeArchetype
|
||||||
|
{
|
||||||
|
TypeID = 40,
|
||||||
|
Title = "Rectangle Mask",
|
||||||
|
Description = "Creates a rectangle mask",
|
||||||
|
Flags = NodeFlags.MaterialGraph,
|
||||||
|
Size = new Float2(150, 40),
|
||||||
|
ConnectionsHints = ConnectionsHint.Vector,
|
||||||
|
DefaultValues = new object[]
|
||||||
|
{
|
||||||
|
new Float2(0.5f, 0.5f),
|
||||||
|
},
|
||||||
|
Elements = new[]
|
||||||
|
{
|
||||||
|
NodeElementArchetype.Factory.Input(0, "UV", true, typeof(Float2), 0),
|
||||||
|
NodeElementArchetype.Factory.Input(1, "Rectangle", true, typeof(Float2), 1, 0),
|
||||||
|
NodeElementArchetype.Factory.Output(0, string.Empty, typeof(float), 2),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new NodeArchetype
|
||||||
|
{
|
||||||
|
TypeID = 41,
|
||||||
|
Title = "FWidth",
|
||||||
|
Description = "Creates a partial derivative (fwidth)",
|
||||||
|
Flags = NodeFlags.MaterialGraph,
|
||||||
|
Size = new Float2(150, 20),
|
||||||
|
ConnectionsHints = ConnectionsHint.Numeric,
|
||||||
|
IndependentBoxes = new[] { 0 },
|
||||||
|
DependentBoxes = new[] { 1 },
|
||||||
|
Elements = new[]
|
||||||
|
{
|
||||||
|
NodeElementArchetype.Factory.Input(0, "Value", true, null, 0),
|
||||||
|
NodeElementArchetype.Factory.Output(0, string.Empty, null, 1),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new NodeArchetype
|
||||||
|
{
|
||||||
|
TypeID = 42,
|
||||||
|
Title = "AA Step",
|
||||||
|
Description = "Smooth version of step function with less aliasing",
|
||||||
|
Flags = NodeFlags.MaterialGraph,
|
||||||
|
Size = new Float2(150, 40),
|
||||||
|
ConnectionsHints = ConnectionsHint.Vector,
|
||||||
|
DefaultValues = new object[]
|
||||||
|
{
|
||||||
|
0.5f
|
||||||
|
},
|
||||||
|
Elements = new[]
|
||||||
|
{
|
||||||
|
NodeElementArchetype.Factory.Input(0, "Value", true, typeof(float), 0),
|
||||||
|
NodeElementArchetype.Factory.Input(1, "Gradient", true, typeof(float), 1, 0),
|
||||||
|
NodeElementArchetype.Factory.Output(0, string.Empty, typeof(float), 2),
|
||||||
|
}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,11 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
public static class Math
|
public static class Math
|
||||||
{
|
{
|
||||||
private static NodeArchetype Op1(ushort id, string title, string desc, ConnectionsHint hints = ConnectionsHint.Numeric, Type type = null)
|
private static NodeArchetype Op1(ushort id, string title, string desc, ConnectionsHint hints = ConnectionsHint.Numeric, Type type = null)
|
||||||
|
{
|
||||||
|
return Op1(id, title, desc, null, hints, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static NodeArchetype Op1(ushort id, string title, string desc, string[] altTitles, ConnectionsHint hints = ConnectionsHint.Numeric, Type type = null)
|
||||||
{
|
{
|
||||||
return new NodeArchetype
|
return new NodeArchetype
|
||||||
{
|
{
|
||||||
@@ -20,6 +25,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
Title = title,
|
Title = title,
|
||||||
Description = desc,
|
Description = desc,
|
||||||
Flags = NodeFlags.AllGraphs,
|
Flags = NodeFlags.AllGraphs,
|
||||||
|
AlternativeTitles = altTitles,
|
||||||
Size = new Float2(110, 20),
|
Size = new Float2(110, 20),
|
||||||
DefaultType = new ScriptType(type),
|
DefaultType = new ScriptType(type),
|
||||||
ConnectionsHints = hints,
|
ConnectionsHints = hints,
|
||||||
@@ -92,6 +98,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
{
|
{
|
||||||
TypeID = 11,
|
TypeID = 11,
|
||||||
Title = "Length",
|
Title = "Length",
|
||||||
|
AlternativeTitles = new[] { "Magnitude", "Mag" },
|
||||||
Description = "Returns the length of A vector",
|
Description = "Returns the length of A vector",
|
||||||
Flags = NodeFlags.AllGraphs,
|
Flags = NodeFlags.AllGraphs,
|
||||||
Size = new Float2(110, 20),
|
Size = new Float2(110, 20),
|
||||||
@@ -107,10 +114,10 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
Op1(13, "Round", "Rounds A to the nearest integer"),
|
Op1(13, "Round", "Rounds A to the nearest integer"),
|
||||||
Op1(14, "Saturate", "Clamps A to the range [0, 1]"),
|
Op1(14, "Saturate", "Clamps A to the range [0, 1]"),
|
||||||
Op1(15, "Sine", "Returns sine of A"),
|
Op1(15, "Sine", "Returns sine of A"),
|
||||||
Op1(16, "Sqrt", "Returns square root of A"),
|
Op1(16, "Sqrt", "Returns square root of A", new [] { "Square Root", "Square", "Root" }),
|
||||||
Op1(17, "Tangent", "Returns tangent of A"),
|
Op1(17, "Tangent", "Returns tangent of A"),
|
||||||
Op2(18, "Cross", "Returns the cross product of A and B", ConnectionsHint.None, typeof(Float3)),
|
Op2(18, "Cross", "Returns the cross product of A and B", ConnectionsHint.None, typeof(Float3)),
|
||||||
Op2(19, "Distance", "Returns a distance scalar between A and B", ConnectionsHint.Vector, null, typeof(float), false),
|
Op2(19, "Distance", "Returns a distance scalar between A and B", new [] { "Magnitude", "Mag", "Length" }, ConnectionsHint.Vector, null, typeof(float), false),
|
||||||
Op2(20, "Dot", "Returns the dot product of A and B", ConnectionsHint.Vector, null, typeof(float), false),
|
Op2(20, "Dot", "Returns the dot product of A and B", ConnectionsHint.Vector, null, typeof(float), false),
|
||||||
Op2(21, "Max", "Selects the greater of A and B"),
|
Op2(21, "Max", "Selects the greater of A and B"),
|
||||||
Op2(22, "Min", "Selects the lesser of A and B"),
|
Op2(22, "Min", "Selects the lesser of A and B"),
|
||||||
@@ -185,7 +192,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
//
|
//
|
||||||
Op1(27, "Negate", "Returns opposite value"),
|
Op1(27, "Negate", "Returns opposite value", new [] { "Invert" }),
|
||||||
Op1(28, "One Minus", "Returns 1 - value"),
|
Op1(28, "One Minus", "Returns 1 - value"),
|
||||||
//
|
//
|
||||||
new NodeArchetype
|
new NodeArchetype
|
||||||
@@ -225,6 +232,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
{
|
{
|
||||||
TypeID = 31,
|
TypeID = 31,
|
||||||
Title = "Mad",
|
Title = "Mad",
|
||||||
|
AlternativeTitles = new [] { "Multiply", "Add", "*+" },
|
||||||
Description = "Performs value multiplication and addition at once",
|
Description = "Performs value multiplication and addition at once",
|
||||||
Flags = NodeFlags.AllGraphs,
|
Flags = NodeFlags.AllGraphs,
|
||||||
Size = new Float2(160, 60),
|
Size = new Float2(160, 60),
|
||||||
|
|||||||
@@ -1084,7 +1084,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
},
|
},
|
||||||
Elements = new[]
|
Elements = new[]
|
||||||
{
|
{
|
||||||
NodeElementArchetype.Factory.Input(0, string.Empty, true, typeof(void), 0),
|
NodeElementArchetype.Factory.Input(0, string.Empty, false, typeof(void), 0),
|
||||||
NodeElementArchetype.Factory.Input(1, string.Empty, true, ScriptType.Null, 1, 1),
|
NodeElementArchetype.Factory.Input(1, string.Empty, true, ScriptType.Null, 1, 1),
|
||||||
NodeElementArchetype.Factory.Output(0, string.Empty, typeof(void), 2, true),
|
NodeElementArchetype.Factory.Output(0, string.Empty, typeof(void), 2, true),
|
||||||
NodeElementArchetype.Factory.ComboBox(2 + 20, 0, 116)
|
NodeElementArchetype.Factory.ComboBox(2 + 20, 0, 116)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using FlaxEditor.Content.Settings;
|
using FlaxEditor.Content.Settings;
|
||||||
using FlaxEditor.GUI;
|
using FlaxEditor.GUI;
|
||||||
|
using FlaxEditor.Scripting;
|
||||||
using FlaxEngine;
|
using FlaxEngine;
|
||||||
|
|
||||||
namespace FlaxEditor.Surface.Archetypes
|
namespace FlaxEditor.Surface.Archetypes
|
||||||
@@ -95,6 +96,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
{
|
{
|
||||||
TypeID = 1,
|
TypeID = 1,
|
||||||
Title = "Texture",
|
Title = "Texture",
|
||||||
|
Create = (id, context, arch, groupArch) => new Constants.ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(Texture))),
|
||||||
Description = "Two dimensional texture object",
|
Description = "Two dimensional texture object",
|
||||||
Flags = NodeFlags.MaterialGraph,
|
Flags = NodeFlags.MaterialGraph,
|
||||||
Size = new Float2(140, 120),
|
Size = new Float2(140, 120),
|
||||||
@@ -131,6 +133,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
{
|
{
|
||||||
TypeID = 3,
|
TypeID = 3,
|
||||||
Title = "Cube Texture",
|
Title = "Cube Texture",
|
||||||
|
Create = (id, context, arch, groupArch) => new Constants.ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(CubeTexture))),
|
||||||
Description = "Set of 6 textures arranged in a cube",
|
Description = "Set of 6 textures arranged in a cube",
|
||||||
Flags = NodeFlags.MaterialGraph,
|
Flags = NodeFlags.MaterialGraph,
|
||||||
Size = new Float2(140, 120),
|
Size = new Float2(140, 120),
|
||||||
@@ -154,6 +157,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
{
|
{
|
||||||
TypeID = 4,
|
TypeID = 4,
|
||||||
Title = "Normal Map",
|
Title = "Normal Map",
|
||||||
|
Create = (id, context, arch, groupArch) => new Constants.ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(NormalMap))),
|
||||||
Description = "Two dimensional texture object sampled as a normal map",
|
Description = "Two dimensional texture object sampled as a normal map",
|
||||||
Flags = NodeFlags.MaterialGraph,
|
Flags = NodeFlags.MaterialGraph,
|
||||||
Size = new Float2(140, 120),
|
Size = new Float2(140, 120),
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user