Merge branch 'master' of https://github.com/FlaxEngine/FlaxEngine into indirect-vulkan
This commit is contained in:
9
.github/workflows/build_linux.yml
vendored
9
.github/workflows/build_linux.yml
vendored
@@ -8,15 +8,18 @@ jobs:
|
||||
name: Editor (Linux, Development x64)
|
||||
runs-on: "ubuntu-20.04"
|
||||
steps:
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
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: Checkout repo
|
||||
uses: actions/checkout@v2
|
||||
- name: Checkout LFS
|
||||
run: |
|
||||
git lfs version
|
||||
git lfs pull
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo rm -f /etc/apt/sources.list.d/*
|
||||
sudo cp -f .github/workflows/build_linux_sources.list /etc/apt/sources.list
|
||||
sudo apt-get update
|
||||
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
|
||||
run: |
|
||||
./Development/Scripts/Linux/CallBuildTool.sh -build -log -arch=x64 -platform=Linux -configuration=Development -buildtargets=FlaxEditor
|
||||
|
||||
4
.github/workflows/build_linux_sources.list
vendored
Normal file
4
.github/workflows/build_linux_sources.list
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
deb http://archive.ubuntu.com/ubuntu/ focal main restricted universe multiverse
|
||||
deb http://archive.ubuntu.com/ubuntu/ focal-updates main restricted universe multiverse
|
||||
deb http://archive.ubuntu.com/ubuntu/ focal-security main restricted universe multiverse
|
||||
deb http://archive.ubuntu.com/ubuntu/ focal-backports main restricted universe multiverse
|
||||
BIN
Content/Editor/IconsAtlas.flax
(Stored with Git LFS)
BIN
Content/Editor/IconsAtlas.flax
(Stored with Git LFS)
Binary file not shown.
23
Content/Editor/Scripting/CppAssetTemplate.h
Normal file
23
Content/Editor/Scripting/CppAssetTemplate.h
Normal file
@@ -0,0 +1,23 @@
|
||||
%copyright%
|
||||
#pragma once
|
||||
|
||||
#include "Engine/Core/ISerializable.h"
|
||||
#include "Engine/Core/Types/BaseTypes.h"
|
||||
#include "Engine/Content/Assets/Model.h"
|
||||
#include "Engine/Scripting/ScriptingType.h"
|
||||
|
||||
/// <summary>
|
||||
/// %class% Json Asset.
|
||||
/// </summary>
|
||||
API_CLASS() class %module%%class% : public ISerializable
|
||||
{
|
||||
API_AUTO_SERIALIZATION();
|
||||
DECLARE_SCRIPTING_TYPE_NO_SPAWN(%class%);
|
||||
public:
|
||||
// Custom float value.
|
||||
API_FIELD(Attributes = "Range(0, 20), EditorOrder(0), EditorDisplay(\"Data\")")
|
||||
float FloatValue = 20.0f;
|
||||
// Custom vector data.
|
||||
API_FIELD(Attributes = "EditorOrder(1), EditorDisplay(\"Data\")")
|
||||
Vector3 Vector3Value = Vector3(0.1f);
|
||||
};
|
||||
8
Content/Editor/Scripting/CppStaticClassTemplate.cpp
Normal file
8
Content/Editor/Scripting/CppStaticClassTemplate.cpp
Normal file
@@ -0,0 +1,8 @@
|
||||
%copyright%
|
||||
#include "%filename%.h"
|
||||
#include "Engine/Core/Log.h"
|
||||
|
||||
void %class%::RunNativeAction(Vector4 data)
|
||||
{
|
||||
LOG(Warning, "Data in RunNativeAction: {0}", data);
|
||||
}
|
||||
20
Content/Editor/Scripting/CppStaticClassTemplate.h
Normal file
20
Content/Editor/Scripting/CppStaticClassTemplate.h
Normal file
@@ -0,0 +1,20 @@
|
||||
%copyright%
|
||||
#pragma once
|
||||
|
||||
#include "Engine/Scripting/Script.h"
|
||||
#include "Engine/Core/Math/Vector4.h"
|
||||
|
||||
/// <summary>
|
||||
/// %class% Function Library
|
||||
/// </summary>
|
||||
API_CLASS(Static) class %module%%class%
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_MINIMAL(%class%);
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Logs the function parameter natively.
|
||||
/// </summary>
|
||||
/// <param name="data">Data to pass to native code</param>
|
||||
API_FUNCTION() static void RunNativeAction(Vector4 data);
|
||||
};
|
||||
@@ -4,23 +4,30 @@ using FlaxEngine;
|
||||
|
||||
namespace %namespace%
|
||||
{
|
||||
/// <summary>
|
||||
/// %class% Script.
|
||||
/// </summary>
|
||||
public class %class% : Script
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public override void OnStart()
|
||||
{
|
||||
// Here you can add code that needs to be called when script is created, just before the first game update
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void OnEnable()
|
||||
{
|
||||
// Here you can add code that needs to be called when script is enabled (eg. register for events)
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void OnDisable()
|
||||
{
|
||||
// Here you can add code that needs to be called when script is disabled (eg. unregister from events)
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void OnUpdate()
|
||||
{
|
||||
// Here you can add code that needs to be called every frame
|
||||
|
||||
BIN
Content/Shaders/BitonicSort.flax
(Stored with Git LFS)
BIN
Content/Shaders/BitonicSort.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Shaders/DepthOfField.flax
(Stored with Git LFS)
BIN
Content/Shaders/DepthOfField.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Shaders/EyeAdaptation.flax
(Stored with Git LFS)
BIN
Content/Shaders/EyeAdaptation.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Shaders/GUI.flax
(Stored with Git LFS)
BIN
Content/Shaders/GUI.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Shaders/VolumetricFog.flax
(Stored with Git LFS)
BIN
Content/Shaders/VolumetricFog.flax
(Stored with Git LFS)
Binary file not shown.
@@ -5,6 +5,7 @@ Custom fork: [https://github.com/FlaxEngine/mono](https://github.com/FlaxEngine/
|
||||
### Notes
|
||||
|
||||
Some useful notes and tips for devs:
|
||||
* Use `-monolog` to print Mono logs to Flax logs
|
||||
* When working with mono fork set `localRepoPath` to local repo location in `Source\Tools\Flax.Build\Deps\Dependencies\mono.cs`
|
||||
* To update mono deps when developing/updating use `.\Development\Scripts\Windows\CallBuildTool.bat -log -ReBuildDeps -verbose -depsToBuild=mono -platform=Windows`, then build engine and run it
|
||||
* `MONO_GC_DEBUG=check-remset-consistency` - it will do additional checks at each collection to see if there are any missing write barriers
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "Editor/Editor.h"
|
||||
#include "Editor/ProjectInfo.h"
|
||||
#include "Engine/Engine/EngineService.h"
|
||||
#include "Engine/Engine/Globals.h"
|
||||
#include "Engine/Graphics/GPUDevice.h"
|
||||
#include "Engine/Utilities/StringConverter.h"
|
||||
#include "FlaxEngine.Gen.h"
|
||||
|
||||
@@ -53,6 +53,11 @@ namespace FlaxEditor.Content.Create
|
||||
/// </summary>
|
||||
NavigationSettings,
|
||||
|
||||
/// <summary>
|
||||
/// The localization settings.
|
||||
/// </summary>
|
||||
LocalizationSettings,
|
||||
|
||||
/// <summary>
|
||||
/// The build settings.
|
||||
/// </summary>
|
||||
@@ -108,6 +113,7 @@ namespace FlaxEditor.Content.Create
|
||||
typeof(PhysicsSettings),
|
||||
typeof(GraphicsSettings),
|
||||
typeof(NavigationSettings),
|
||||
typeof(LocalizationSettings),
|
||||
typeof(BuildSettings),
|
||||
typeof(InputSettings),
|
||||
typeof(WindowsPlatformSettings),
|
||||
|
||||
@@ -116,8 +116,7 @@ namespace FlaxEditor.Content.Import
|
||||
if (FileTypes.TryGetValue(extension, out ImportFileEntryHandler createDelegate))
|
||||
return createDelegate(ref request);
|
||||
|
||||
// Use default type
|
||||
return request.IsBinaryAsset ? new AssetImportEntry(ref request) : new ImportFileEntry(ref request);
|
||||
return request.IsInBuilt ? new AssetImportEntry(ref request) : new ImportFileEntry(ref request);
|
||||
}
|
||||
|
||||
internal static void RegisterDefaultTypes()
|
||||
|
||||
@@ -21,9 +21,9 @@ namespace FlaxEditor.Content.Import
|
||||
public string OutputPath;
|
||||
|
||||
/// <summary>
|
||||
/// Flag set to true for binary assets handled by the engine internally.
|
||||
/// Flag set to true for the assets handled by the engine internally.
|
||||
/// </summary>
|
||||
public bool IsBinaryAsset;
|
||||
public bool IsInBuilt;
|
||||
|
||||
/// <summary>
|
||||
/// Flag used to skip showing import settings dialog to used. Can be used for importing assets from code by plugins.
|
||||
|
||||
@@ -483,7 +483,9 @@ namespace FlaxEditor.Content.Import
|
||||
{
|
||||
if (settings is TextureImportSettings o)
|
||||
{
|
||||
var sprites = o.Sprites ?? _settings.Sprites; // Preserve sprites if not specified to override
|
||||
_settings = o;
|
||||
_settings.Sprites = sprites;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -20,6 +20,6 @@ namespace FlaxEditor.Content
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SpriteHandle DefaultThumbnail => Editor.Instance.Icons.CSharpScript64;
|
||||
public override SpriteHandle DefaultThumbnail => Editor.Instance.Icons.CSharpScript128;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ namespace FlaxEditor.Content
|
||||
public override bool Exists => Directory.Exists(Path);
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SpriteHandle DefaultThumbnail => Editor.Instance.Icons.Folder64;
|
||||
public override SpriteHandle DefaultThumbnail => Editor.Instance.Icons.Folder128;
|
||||
|
||||
/// <inheritdoc />
|
||||
internal override void UpdatePath(string value)
|
||||
|
||||
@@ -455,7 +455,7 @@ namespace FlaxEditor.Content
|
||||
const float thumbnailInShadowSize = 50.0f;
|
||||
var shadowRect = rectangle.MakeExpanded((DefaultThumbnailSize - thumbnailInShadowSize) * rectangle.Width / DefaultThumbnailSize * 1.3f);
|
||||
if (!_shadowIcon.IsValid)
|
||||
_shadowIcon = Editor.Instance.Icons.AssetShadow;
|
||||
_shadowIcon = Editor.Instance.Icons.AssetShadow128;
|
||||
Render2D.DrawSprite(_shadowIcon, shadowRect);
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,6 @@ namespace FlaxEditor.Content
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SpriteHandle DefaultThumbnail => Editor.Instance.Icons.CppScript64;
|
||||
public override SpriteHandle DefaultThumbnail => Editor.Instance.Icons.CPPScript128;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,6 @@ namespace FlaxEditor.Content
|
||||
public override ContentItemSearchFilter SearchFilter => ContentItemSearchFilter.Other;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SpriteHandle DefaultThumbnail => Editor.Instance.Icons.Document64;
|
||||
public override SpriteHandle DefaultThumbnail => Editor.Instance.Icons.Document128;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,8 @@ namespace FlaxEditor.Content
|
||||
/// <seealso cref="FlaxEditor.Content.AssetItem" />
|
||||
public class JsonAssetItem : AssetItem
|
||||
{
|
||||
private readonly SpriteHandle _thumbnail;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="JsonAssetItem"/> class.
|
||||
/// </summary>
|
||||
@@ -20,13 +22,27 @@ namespace FlaxEditor.Content
|
||||
public JsonAssetItem(string path, Guid id, string typeName)
|
||||
: base(path, typeName, ref id)
|
||||
{
|
||||
_thumbnail = Editor.Instance.Icons.Document128;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="JsonAssetItem"/> class.
|
||||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
/// <param name="id">The identifier.</param>
|
||||
/// <param name="typeName">Name of the resource type.</param>
|
||||
/// <param name="thumbnail">Asset icon.</param>
|
||||
public JsonAssetItem(string path, Guid id, string typeName, SpriteHandle thumbnail)
|
||||
: base(path, typeName, ref id)
|
||||
{
|
||||
_thumbnail = thumbnail;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override ContentItemSearchFilter SearchFilter => ContentItemSearchFilter.Json;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SpriteHandle DefaultThumbnail => Editor.Instance.Icons.Document64;
|
||||
public override SpriteHandle DefaultThumbnail => _thumbnail;
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override bool DrawShadow => false;
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace FlaxEditor.Content
|
||||
public override ContentItemSearchFilter SearchFilter => ContentItemSearchFilter.Other;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SpriteHandle DefaultThumbnail => Editor.Instance.Icons.Document64;
|
||||
public override SpriteHandle DefaultThumbnail => Editor.Instance.Icons.Document128;
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override bool DrawShadow => true;
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace FlaxEditor.Content
|
||||
public override ContentItemSearchFilter SearchFilter => ContentItemSearchFilter.Scene;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SpriteHandle DefaultThumbnail => Editor.Instance.Icons.Scene64;
|
||||
public override SpriteHandle DefaultThumbnail => Editor.Instance.Icons.Scene128;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool IsOfType(Type type)
|
||||
|
||||
@@ -27,6 +27,6 @@ namespace FlaxEditor.Content
|
||||
public override ContentItemSearchFilter SearchFilter => ContentItemSearchFilter.Shader;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SpriteHandle DefaultThumbnail => Editor.Instance.Icons.Document64;
|
||||
public override SpriteHandle DefaultThumbnail => Editor.Instance.Icons.Document128;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -539,7 +539,7 @@ namespace FlaxEditor.Content
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SpriteHandle DefaultThumbnail => Editor.Instance.Icons.CodeScript64;
|
||||
public override SpriteHandle DefaultThumbnail => Editor.Instance.Icons.VisualScript128;
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override bool DrawShadow => false;
|
||||
|
||||
@@ -76,7 +76,7 @@ void PreviewsCache::FlushTask::OnEnd()
|
||||
ThreadPoolTask::OnEnd();
|
||||
}
|
||||
|
||||
REGISTER_BINARY_ASSET(PreviewsCache, "FlaxEditor.PreviewsCache", ::New<TextureAssetUpgrader>(), false);
|
||||
REGISTER_BINARY_ASSET_WITH_UPGRADER(PreviewsCache, "FlaxEditor.PreviewsCache", TextureAssetUpgrader, false);
|
||||
|
||||
PreviewsCache::PreviewsCache(const SpawnParams& params, const AssetInfo* info)
|
||||
: SpriteAtlas(params, info)
|
||||
|
||||
@@ -73,6 +73,16 @@ namespace FlaxEditor.Content
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified filename is valid for this proxy.
|
||||
/// </summary>
|
||||
/// <param name="filename">The filename.</param>
|
||||
/// <returns><c>true</c> if the filename is valid, otherwise <c>false</c>.</returns>
|
||||
public virtual bool IsFileNameValid(string filename)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether this proxy can create items in the specified target location.
|
||||
/// </summary>
|
||||
|
||||
134
Source/Editor/Content/Proxy/CppProxy.cs
Normal file
134
Source/Editor/Content/Proxy/CppProxy.cs
Normal file
@@ -0,0 +1,134 @@
|
||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using FlaxEditor.Content.Settings;
|
||||
using FlaxEngine;
|
||||
|
||||
namespace FlaxEditor.Content
|
||||
{
|
||||
/// <summary>
|
||||
/// Context proxy object for C++ files.
|
||||
/// </summary>
|
||||
/// <seealso cref="FlaxEditor.Content.CSharpScriptProxy" />
|
||||
public abstract class CppProxy : ScriptProxy
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the paths for header and source files to format.
|
||||
/// </summary>
|
||||
/// <param name="headerTemplate">The header template path.</param>
|
||||
/// <param name="sourceTemplate">The source template path.</param>
|
||||
protected abstract void GetTemplatePaths(out string headerTemplate, out string sourceTemplate);
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool IsProxyFor(ContentItem item)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Create(string outputPath, object arg)
|
||||
{
|
||||
// Find the module that this script is being added (based on the path)
|
||||
var module = string.Empty;
|
||||
var project = TryGetProjectAtFolder(outputPath, out var moduleName);
|
||||
if (project != null)
|
||||
{
|
||||
module = moduleName.ToUpperInvariant() + "_API ";
|
||||
}
|
||||
|
||||
var gameSettings = GameSettings.Load();
|
||||
var scriptName = ScriptItem.CreateScriptName(outputPath);
|
||||
var filename = Path.GetFileNameWithoutExtension(outputPath);
|
||||
var copyrightComment = string.IsNullOrEmpty(gameSettings.CopyrightNotice) ? string.Empty : string.Format("// {0}{1}{1}", gameSettings.CopyrightNotice, Environment.NewLine);
|
||||
|
||||
GetTemplatePaths(out var headerTemplatePath, out var sourceTemplatePath);
|
||||
if (headerTemplatePath != null)
|
||||
{
|
||||
var headerTemplate = File.ReadAllText(headerTemplatePath);
|
||||
headerTemplate = headerTemplate.Replace("%copyright%", copyrightComment);
|
||||
headerTemplate = headerTemplate.Replace("%class%", scriptName);
|
||||
headerTemplate = headerTemplate.Replace("%module%", module);
|
||||
headerTemplate = headerTemplate.Replace("%filename%", filename);
|
||||
File.WriteAllText(Path.ChangeExtension(outputPath, ".h"), headerTemplate, Encoding.UTF8);
|
||||
}
|
||||
if (sourceTemplatePath != null)
|
||||
{
|
||||
var sourceTemplate = File.ReadAllText(sourceTemplatePath);
|
||||
sourceTemplate = sourceTemplate.Replace("%copyright%", copyrightComment);
|
||||
sourceTemplate = sourceTemplate.Replace("%class%", scriptName);
|
||||
sourceTemplate = sourceTemplate.Replace("%module%", module);
|
||||
sourceTemplate = sourceTemplate.Replace("%filename%", filename);
|
||||
File.WriteAllText(outputPath, sourceTemplate, Encoding.UTF8);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string FileExtension => "cpp";
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Color AccentColor => Color.FromRGB(0x9c1c9c);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Context proxy object for C++ script files.
|
||||
/// </summary>
|
||||
/// <seealso cref="FlaxEditor.Content.CSharpScriptProxy" />
|
||||
public class CppScriptProxy : CppProxy
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override string Name => "C++ Script";
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool IsProxyFor(ContentItem item)
|
||||
{
|
||||
return item is CppScriptItem;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void GetTemplatePaths(out string headerTemplate, out string sourceTemplate)
|
||||
{
|
||||
headerTemplate = StringUtils.CombinePaths(Globals.EngineContentFolder, "Editor/Scripting/ScriptTemplate.h");
|
||||
sourceTemplate = StringUtils.CombinePaths(Globals.EngineContentFolder, "Editor/Scripting/ScriptTemplate.cpp");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Context proxy object for C++ Json Asset files.
|
||||
/// </summary>
|
||||
/// <seealso cref="FlaxEditor.Content.CSharpScriptProxy" />
|
||||
public class CppStaticClassProxy : CppProxy
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override string Name => "C++ Function Library";
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void GetTemplatePaths(out string headerTemplate, out string sourceTemplate)
|
||||
{
|
||||
headerTemplate = StringUtils.CombinePaths(Globals.EngineContentFolder, "Editor/Scripting/CppStaticClassTemplate.h");
|
||||
sourceTemplate = StringUtils.CombinePaths(Globals.EngineContentFolder, "Editor/Scripting/CppStaticClassTemplate.cpp");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Context proxy object for C++ Json Asset files.
|
||||
/// </summary>
|
||||
/// <seealso cref="FlaxEditor.Content.CSharpScriptProxy" />
|
||||
public class CppAssetProxy : CppProxy
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override string Name => "C++ Json Asset";
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void GetTemplatePaths(out string headerTemplate, out string sourceTemplate)
|
||||
{
|
||||
headerTemplate = null;
|
||||
sourceTemplate = StringUtils.CombinePaths(Globals.EngineContentFolder, "Editor/Scripting/CppAssetTemplate.h");
|
||||
//sourceTemplate = StringUtils.CombinePaths(Globals.EngineContentFolder, "Editor/Scripting/CppAssetTemplate.cpp");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string FileExtension => "h";
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using FlaxEditor.Content.Settings;
|
||||
using FlaxEngine;
|
||||
|
||||
namespace FlaxEditor.Content
|
||||
{
|
||||
/// <summary>
|
||||
/// Context proxy object for C++ script files.
|
||||
/// </summary>
|
||||
/// <seealso cref="FlaxEditor.Content.CSharpScriptProxy" />
|
||||
public class CppScriptProxy : ScriptProxy
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override string Name => "C++ Script";
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool IsProxyFor(ContentItem item)
|
||||
{
|
||||
return item is CppScriptItem;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Create(string outputPath, object arg)
|
||||
{
|
||||
// Load templates
|
||||
var headerTemplate = File.ReadAllText(StringUtils.CombinePaths(Globals.EngineContentFolder, "Editor/Scripting/ScriptTemplate.h"));
|
||||
var sourceTemplate = File.ReadAllText(StringUtils.CombinePaths(Globals.EngineContentFolder, "Editor/Scripting/ScriptTemplate.cpp"));
|
||||
|
||||
// Find the module that this script is being added (based on the path)
|
||||
var module = string.Empty;
|
||||
var project = TryGetProjectAtFolder(outputPath, out var moduleName);
|
||||
if (project != null)
|
||||
{
|
||||
module = moduleName.ToUpperInvariant() + "_API ";
|
||||
}
|
||||
|
||||
// Format
|
||||
var gameSettings = GameSettings.Load();
|
||||
var scriptName = ScriptItem.CreateScriptName(outputPath);
|
||||
var filename = Path.GetFileNameWithoutExtension(outputPath);
|
||||
var copyrightComment = string.IsNullOrEmpty(gameSettings.CopyrightNotice) ? string.Empty : string.Format("// {0}{1}{1}", gameSettings.CopyrightNotice, Environment.NewLine);
|
||||
headerTemplate = headerTemplate.Replace("%copyright%", copyrightComment);
|
||||
headerTemplate = headerTemplate.Replace("%class%", scriptName);
|
||||
headerTemplate = headerTemplate.Replace("%module%", module);
|
||||
sourceTemplate = sourceTemplate.Replace("%filename%", filename);
|
||||
sourceTemplate = sourceTemplate.Replace("%copyright%", copyrightComment);
|
||||
sourceTemplate = sourceTemplate.Replace("%class%", scriptName);
|
||||
sourceTemplate = sourceTemplate.Replace("%filename%", filename);
|
||||
|
||||
// Save
|
||||
File.WriteAllText(Path.ChangeExtension(outputPath, ".h"), headerTemplate, Encoding.UTF8);
|
||||
File.WriteAllText(outputPath, sourceTemplate, Encoding.UTF8);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string FileExtension => "cpp";
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Color AccentColor => Color.FromRGB(0x9c1c9c);
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
using System;
|
||||
using FlaxEditor.Content.Create;
|
||||
using FlaxEditor.Content.Settings;
|
||||
using FlaxEditor.CustomEditors;
|
||||
using FlaxEditor.CustomEditors.Editors;
|
||||
using FlaxEditor.Windows;
|
||||
@@ -45,18 +44,12 @@ namespace FlaxEditor.Content
|
||||
/// <inheritdoc />
|
||||
public override bool IsProxyFor(ContentItem item)
|
||||
{
|
||||
return item is JsonAssetItem;
|
||||
return item is JsonAssetItem json && json.TypeName == TypeName;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Color AccentColor => Color.FromRGB(0xd14f67);
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool AcceptsAsset(string typeName, string path)
|
||||
{
|
||||
return typeName == TypeName && base.AcceptsAsset(typeName, path);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override AssetItem ConstructItem(string path, string typeName, ref Guid id)
|
||||
{
|
||||
@@ -143,6 +136,12 @@ namespace FlaxEditor.Content
|
||||
return path.EndsWith(FileExtension, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool IsProxyFor(ContentItem item)
|
||||
{
|
||||
return item is JsonAssetItem;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool CanCreate(ContentFolder targetLocation)
|
||||
{
|
||||
|
||||
24
Source/Editor/Content/Proxy/LocalizedStringTableProxy.cs
Normal file
24
Source/Editor/Content/Proxy/LocalizedStringTableProxy.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||
|
||||
using FlaxEditor.Windows;
|
||||
using FlaxEditor.Windows.Assets;
|
||||
using FlaxEngine;
|
||||
|
||||
namespace FlaxEditor.Content
|
||||
{
|
||||
/// <summary>
|
||||
/// <see cref="LocalizedStringTable"/> proxy.
|
||||
/// </summary>
|
||||
/// <seealso cref="FlaxEditor.Content.JsonAssetProxy" />
|
||||
public class LocalizedStringTableProxy : JsonAssetProxy
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override EditorWindow Open(Editor editor, ContentItem item)
|
||||
{
|
||||
return new LocalizedStringTableWindow(editor, (JsonAssetItem)item);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string TypeName => "FlaxEngine.LocalizedStringTable";
|
||||
}
|
||||
}
|
||||
@@ -66,6 +66,15 @@ namespace FlaxEditor.Content
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool IsFileNameValid(string filename)
|
||||
{
|
||||
// Scripts cannot start with digit.
|
||||
if (Char.IsDigit(filename[0]))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Create(string outputPath, object arg)
|
||||
{
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
using System;
|
||||
using FlaxEditor.Content.Create;
|
||||
using FlaxEditor.Content.Settings;
|
||||
using FlaxEngine;
|
||||
|
||||
namespace FlaxEditor.Content
|
||||
{
|
||||
@@ -13,15 +14,18 @@ namespace FlaxEditor.Content
|
||||
public sealed class SettingsProxy : JsonAssetProxy
|
||||
{
|
||||
private readonly Type _type;
|
||||
private readonly SpriteHandle _thumbnail;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SettingsProxy"/> class.
|
||||
/// </summary>
|
||||
/// <param name="type">The settings asset type (must be subclass of SettingsBase type).</param>
|
||||
public SettingsProxy(Type type)
|
||||
/// <param name="thumbnail">Asset icon.</param>
|
||||
public SettingsProxy(Type type, SpriteHandle thumbnail)
|
||||
{
|
||||
_type = type;
|
||||
TypeName = type.FullName;
|
||||
_thumbnail = thumbnail;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -44,6 +48,12 @@ namespace FlaxEditor.Content
|
||||
Editor.Instance.ContentImporting.Create(new SettingsCreateEntry(outputPath));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override AssetItem ConstructItem(string path, string typeName, ref Guid id)
|
||||
{
|
||||
return new JsonAssetItem(path, id, typeName, _thumbnail);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool IsProxyFor<T>()
|
||||
{
|
||||
|
||||
@@ -77,7 +77,7 @@ namespace FlaxEditor.Content
|
||||
/// <param name="type">The folder type.</param>
|
||||
/// <param name="path">The folder path.</param>
|
||||
protected ContentTreeNode(ContentTreeNode parent, ContentFolderType type, string path)
|
||||
: base(false, Editor.Instance.Icons.FolderClosed12, Editor.Instance.Icons.FolderOpened12)
|
||||
: base(false, Editor.Instance.Icons.FolderClosed32, Editor.Instance.Icons.FolderOpen32)
|
||||
{
|
||||
_folder = new ContentFolder(type, path, this);
|
||||
Text = _folder.ShortName;
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "Engine/Core/Collections/Array.h"
|
||||
#include "Engine/Core/Collections/HashSet.h"
|
||||
#include "Engine/Core/Collections/Dictionary.h"
|
||||
#include "Engine/Core/Types/Guid.h"
|
||||
|
||||
class GameCooker;
|
||||
class PlatformTools;
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "Engine/Serialization/JsonTools.h"
|
||||
#include "Engine/Content/Content.h"
|
||||
#include "Engine/Engine/EngineService.h"
|
||||
#include "Engine/Engine/Globals.h"
|
||||
#include "Engine/Threading/ThreadSpawner.h"
|
||||
#include "Engine/Platform/FileSystem.h"
|
||||
#include "Steps/ValidateStep.h"
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "Engine/Graphics/RenderTools.h"
|
||||
#include "Engine/Graphics/Textures/TextureData.h"
|
||||
#include "Engine/Engine/Base/GameBase.h"
|
||||
#include "Engine/Engine/Globals.h"
|
||||
#include "Engine/Tools/TextureTool/TextureTool.h"
|
||||
#if PLATFORM_TOOLS_WINDOWS
|
||||
#include "Engine/Platform/Windows/WindowsPlatformSettings.h"
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "Engine/Core/Config/GameSettings.h"
|
||||
#include "Engine/Renderer/ReflectionsPass.h"
|
||||
#include "Engine/Renderer/AntiAliasing/SMAA.h"
|
||||
#include "Engine/Engine/Globals.h"
|
||||
|
||||
bool DeployDataStep::Perform(CookingData& data)
|
||||
{
|
||||
|
||||
@@ -139,7 +139,7 @@ namespace FlaxEditor.CustomEditors
|
||||
/// <inheritdoc />
|
||||
protected override void OnModified()
|
||||
{
|
||||
Presenter.Modified?.Invoke();
|
||||
Presenter.OnModified();
|
||||
|
||||
base.OnModified();
|
||||
}
|
||||
@@ -354,6 +354,14 @@ namespace FlaxEditor.CustomEditors
|
||||
ExpandGroups(this, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes <see cref="Modified"/> event.
|
||||
/// </summary>
|
||||
public void OnModified()
|
||||
{
|
||||
Modified?.Invoke();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when selection gets changed.
|
||||
/// </summary>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "CustomEditorsUtil.h"
|
||||
#include "Engine/Core/Log.h"
|
||||
#include "Engine/Core/Types/DateTime.h"
|
||||
#include "Engine/Core/Types/TimeSpan.h"
|
||||
#include "Engine/Core/Collections/Dictionary.h"
|
||||
#include "Engine/Engine/EngineService.h"
|
||||
#include "Engine/Scripting/Scripting.h"
|
||||
|
||||
@@ -0,0 +1,429 @@
|
||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using FlaxEditor.Content.Settings;
|
||||
using FlaxEditor.CustomEditors.Editors;
|
||||
using FlaxEditor.Scripting;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
using FlaxEngine.Utilities;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Object = FlaxEngine.Object;
|
||||
|
||||
namespace FlaxEditor.CustomEditors.Dedicated
|
||||
{
|
||||
[CustomEditor(typeof(LocalizationSettings))]
|
||||
sealed class LocalizationSettingsEditor : GenericEditor
|
||||
{
|
||||
private CultureInfo _theMostTranslatedCulture;
|
||||
private int _theMostTranslatedCultureCount;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Initialize(LayoutElementsContainer layout)
|
||||
{
|
||||
Profiler.BeginEvent("LocalizationSettingsEditor.Initialize");
|
||||
var settings = (LocalizationSettings)Values[0];
|
||||
var tablesLength = settings.LocalizedStringTables?.Length ?? 0;
|
||||
var tables = new List<LocalizedStringTable>(tablesLength);
|
||||
for (int i = 0; i < tablesLength; i++)
|
||||
{
|
||||
var table = settings.LocalizedStringTables[i];
|
||||
if (table && !table.WaitForLoaded())
|
||||
tables.Add(table);
|
||||
}
|
||||
var locales = tables.GroupBy(x => x.Locale);
|
||||
var tableEntries = new Dictionary<LocalizedStringTable, Dictionary<string, string[]>>();
|
||||
var allKeys = new HashSet<string>();
|
||||
foreach (var e in locales)
|
||||
{
|
||||
foreach (var table in e)
|
||||
{
|
||||
var entries = table.Entries;
|
||||
tableEntries[table] = entries;
|
||||
allKeys.AddRange(entries.Keys);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
var group = layout.Group("Preview");
|
||||
|
||||
// Current language and culture preview management
|
||||
group.Object("Current Language", new CustomValueContainer(new ScriptType(typeof(CultureInfo)), Localization.CurrentLanguage, (instance, index) => Localization.CurrentLanguage, (instance, index, value) => Localization.CurrentLanguage = value as CultureInfo), null, "Current UI display language for the game preview.");
|
||||
group.Object("Current Culture", new CustomValueContainer(new ScriptType(typeof(CultureInfo)), Localization.CurrentCulture, (instance, index) => Localization.CurrentCulture, (instance, index, value) => Localization.CurrentCulture = value as CultureInfo), null, "Current values formatting culture for the game preview.");
|
||||
}
|
||||
|
||||
{
|
||||
var group = layout.Group("Locales");
|
||||
|
||||
// Show all existing locales
|
||||
_theMostTranslatedCulture = null;
|
||||
_theMostTranslatedCultureCount = -1;
|
||||
foreach (var e in locales)
|
||||
{
|
||||
var culture = new CultureInfo(e.Key);
|
||||
var prop = group.AddPropertyItem(CultureInfoEditor.GetName(culture), culture.NativeName);
|
||||
int count = e.Sum(x => tableEntries[x].Count);
|
||||
int validCount = e.Sum(x => tableEntries[x].Values.Count(y => y != null && y.Length != 0 && !string.IsNullOrEmpty(y[0])));
|
||||
if (count > _theMostTranslatedCultureCount)
|
||||
{
|
||||
_theMostTranslatedCulture = culture;
|
||||
_theMostTranslatedCultureCount = count;
|
||||
}
|
||||
prop.Label(string.Format("Progress: {0}% ({1}/{2})", (int)(((float)validCount / allKeys.Count * 100.0f)), validCount, allKeys.Count));
|
||||
prop.Label("Tables:");
|
||||
foreach (var table in e)
|
||||
{
|
||||
var namePath = table.Path;
|
||||
if (namePath.StartsWith(Globals.ProjectFolder))
|
||||
namePath = namePath.Substring(Globals.ProjectFolder.Length + 1);
|
||||
var tableLabel = prop.ClickableLabel(namePath).CustomControl;
|
||||
tableLabel.TextColorHighlighted = Color.Wheat;
|
||||
tableLabel.DoubleClick += delegate { Editor.Instance.Windows.ContentWin.Select(table); };
|
||||
}
|
||||
group.Space(10);
|
||||
}
|
||||
|
||||
// Update add button
|
||||
var update = group.Button("Update").Button;
|
||||
update.TooltipText = "Refreshes the dashboard statistics";
|
||||
update.Height = 16.0f;
|
||||
update.Clicked += RebuildLayout;
|
||||
|
||||
// New locale add button
|
||||
var addLocale = group.Button("Add Locale...").Button;
|
||||
addLocale.TooltipText = "Shows a locale picker and creates new localization for it with not translated string tables";
|
||||
addLocale.Height = 16.0f;
|
||||
addLocale.ButtonClicked += delegate(Button button)
|
||||
{
|
||||
var menu = CultureInfoEditor.CreatePicker(null, culture =>
|
||||
{
|
||||
var displayName = CultureInfoEditor.GetName(culture);
|
||||
if (locales.Any(x => x.Key == culture.Name))
|
||||
{
|
||||
MessageBox.Show($"Culture '{displayName}' is already added.");
|
||||
return;
|
||||
}
|
||||
Profiler.BeginEvent("LocalizationSettingsEditor.AddLocale");
|
||||
Editor.Log($"Adding culture '{displayName}' to localization settings");
|
||||
var newTables = settings.LocalizedStringTables.ToList();
|
||||
if (_theMostTranslatedCulture != null)
|
||||
{
|
||||
// Duplicate localization for culture with the highest amount of keys
|
||||
var g = locales.First(x => x.Key == _theMostTranslatedCulture.Name);
|
||||
foreach (var e in g)
|
||||
{
|
||||
var path = e.Path;
|
||||
var filename = Path.GetFileNameWithoutExtension(path);
|
||||
if (filename.EndsWith(_theMostTranslatedCulture.Name))
|
||||
filename = filename.Substring(0, filename.Length - _theMostTranslatedCulture.Name.Length);
|
||||
path = Path.Combine(Path.GetDirectoryName(path), filename + culture.Name + ".json");
|
||||
var table = FlaxEngine.Content.CreateVirtualAsset<LocalizedStringTable>();
|
||||
table.Locale = culture.Name;
|
||||
var entries = new Dictionary<string, string[]>();
|
||||
foreach (var ee in tableEntries[e])
|
||||
{
|
||||
var vv = (string[])ee.Value.Clone();
|
||||
for (var i = 0; i < vv.Length; i++)
|
||||
vv[i] = string.Empty;
|
||||
entries.Add(ee.Key, vv);
|
||||
}
|
||||
table.Entries = entries;
|
||||
if (!table.Save(path))
|
||||
{
|
||||
Object.Destroy(table);
|
||||
newTables.Add(FlaxEngine.Content.LoadAsync<LocalizedStringTable>(path));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No localization so initialize with empty table
|
||||
var path = Path.Combine(Path.Combine(Path.GetDirectoryName(GameSettings.Load().Localization.Path), "Localization", culture.Name + ".json"));
|
||||
var table = FlaxEngine.Content.CreateVirtualAsset<LocalizedStringTable>();
|
||||
table.Locale = culture.Name;
|
||||
if (!table.Save(path))
|
||||
{
|
||||
Object.Destroy(table);
|
||||
newTables.Add(FlaxEngine.Content.LoadAsync<LocalizedStringTable>(path));
|
||||
}
|
||||
}
|
||||
settings.LocalizedStringTables = newTables.ToArray();
|
||||
Presenter.OnModified();
|
||||
RebuildLayout();
|
||||
Profiler.EndEvent();
|
||||
});
|
||||
menu.Show(button, new Vector2(0, button.Height));
|
||||
};
|
||||
|
||||
// Export button
|
||||
var exportLocalization = group.Button("Export...").Button;
|
||||
exportLocalization.TooltipText = "Exports the localization strings into .pot file for translation";
|
||||
exportLocalization.Height = 16.0f;
|
||||
exportLocalization.Clicked += delegate
|
||||
{
|
||||
if (FileSystem.ShowSaveFileDialog(null, null, "*.pot", false, "Export localization for translation to .pot file", out var filenames))
|
||||
return;
|
||||
Profiler.BeginEvent("LocalizationSettingsEditor.Export");
|
||||
if (!filenames[0].EndsWith(".pot"))
|
||||
filenames[0] += ".pot";
|
||||
var nplurals = 1;
|
||||
foreach (var e in tableEntries)
|
||||
{
|
||||
foreach (var value in e.Value.Values)
|
||||
{
|
||||
if (value != null && value.Length > nplurals)
|
||||
nplurals = value.Length;
|
||||
}
|
||||
}
|
||||
using (var writer = new StreamWriter(filenames[0], false, Encoding.UTF8))
|
||||
{
|
||||
writer.WriteLine("msgid \"\"");
|
||||
writer.WriteLine("msgstr \"\"");
|
||||
writer.WriteLine("\"Language: English\\n\"");
|
||||
writer.WriteLine("\"MIME-Version: 1.0\\n\"");
|
||||
writer.WriteLine("\"Content-Type: text/plain; charset=UTF-8\\n\"");
|
||||
writer.WriteLine("\"Content-Transfer-Encoding: 8bit\\n\"");
|
||||
writer.WriteLine($"\"Plural-Forms: nplurals={nplurals}; plural=(n != 1);\\n\"");
|
||||
writer.WriteLine("\"X-Generator: FlaxEngine\\n\"");
|
||||
var written = new HashSet<string>();
|
||||
foreach (var e in tableEntries)
|
||||
{
|
||||
foreach (var pair in e.Value)
|
||||
{
|
||||
if (written.Contains(pair.Key))
|
||||
continue;
|
||||
written.Add(pair.Key);
|
||||
|
||||
writer.WriteLine("");
|
||||
writer.WriteLine($"msgid \"{pair.Key}\"");
|
||||
if (pair.Value == null || pair.Value.Length < 2)
|
||||
{
|
||||
writer.WriteLine("msgstr \"\"");
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteLine("msgid_plural \"\"");
|
||||
for (int i = 0; i < pair.Value.Length; i++)
|
||||
writer.WriteLine($"msgstr[{i}] \"\"");
|
||||
}
|
||||
}
|
||||
if (written.Count == allKeys.Count)
|
||||
break;
|
||||
}
|
||||
}
|
||||
Profiler.EndEvent();
|
||||
};
|
||||
|
||||
// Find localized strings in code button
|
||||
var findStringsCode = group.Button("Find localized strings in code").Button;
|
||||
findStringsCode.TooltipText = "Searches for localized string usage in inside a project source files";
|
||||
findStringsCode.Height = 16.0f;
|
||||
findStringsCode.Clicked += delegate
|
||||
{
|
||||
var newKeys = new Dictionary<string, string>();
|
||||
Profiler.BeginEvent("LocalizationSettingsEditor.FindLocalizedStringsInSource");
|
||||
|
||||
// C#
|
||||
var files = Directory.GetFiles(Globals.ProjectSourceFolder, "*.cs", SearchOption.AllDirectories);
|
||||
var filesCount = files.Length;
|
||||
foreach (var file in files)
|
||||
FindNewKeysCSharp(file, newKeys, allKeys);
|
||||
|
||||
// C++
|
||||
files = Directory.GetFiles(Globals.ProjectSourceFolder, "*.cpp", SearchOption.AllDirectories);
|
||||
filesCount += files.Length;
|
||||
foreach (var file in files)
|
||||
FindNewKeysCpp(file, newKeys, allKeys);
|
||||
files = Directory.GetFiles(Globals.ProjectSourceFolder, "*.h", SearchOption.AllDirectories);
|
||||
filesCount += files.Length;
|
||||
foreach (var file in files)
|
||||
FindNewKeysCpp(file, newKeys, allKeys);
|
||||
|
||||
AddNewKeys(newKeys, filesCount, locales, tableEntries);
|
||||
Profiler.EndEvent();
|
||||
};
|
||||
|
||||
// Find localized strings in content button
|
||||
var findStringsContent = group.Button("Find localized strings in content").Button;
|
||||
findStringsContent.TooltipText = "Searches for localized string usage in inside a project content files (scenes, prefabs)";
|
||||
findStringsContent.Height = 16.0f;
|
||||
findStringsContent.Clicked += delegate
|
||||
{
|
||||
var newKeys = new Dictionary<string, string>();
|
||||
Profiler.BeginEvent("LocalizationSettingsEditor.FindLocalizedStringsInContent");
|
||||
|
||||
// Scenes
|
||||
var files = Directory.GetFiles(Globals.ProjectContentFolder, "*.scene", SearchOption.AllDirectories);
|
||||
var filesCount = files.Length;
|
||||
foreach (var file in files)
|
||||
FindNewKeysJson(file, newKeys, allKeys);
|
||||
|
||||
// Prefabs
|
||||
files = Directory.GetFiles(Globals.ProjectContentFolder, "*.prefab", SearchOption.AllDirectories);
|
||||
filesCount += files.Length;
|
||||
foreach (var file in files)
|
||||
FindNewKeysJson(file, newKeys, allKeys);
|
||||
|
||||
AddNewKeys(newKeys, filesCount, locales, tableEntries);
|
||||
Profiler.EndEvent();
|
||||
};
|
||||
}
|
||||
|
||||
{
|
||||
// Raw asset data editing
|
||||
var group = layout.Group("Data");
|
||||
base.Initialize(group);
|
||||
}
|
||||
|
||||
Profiler.EndEvent();
|
||||
}
|
||||
|
||||
private static void FindNewKeysCSharp(string file, Dictionary<string, string> newKeys, HashSet<string> allKeys)
|
||||
{
|
||||
var startToken = "Localization.GetString";
|
||||
var textToken = "\"";
|
||||
FindNewKeys(file, newKeys, allKeys, startToken, textToken);
|
||||
}
|
||||
|
||||
private static void FindNewKeysCpp(string file, Dictionary<string, string> newKeys, HashSet<string> allKeys)
|
||||
{
|
||||
var startToken = "Localization::GetString";
|
||||
var textToken = "TEXT(\"";
|
||||
FindNewKeys(file, newKeys, allKeys, startToken, textToken);
|
||||
}
|
||||
|
||||
private static void FindNewKeys(string file, Dictionary<string, string> newKeys, HashSet<string> allKeys, string startToken, string textToken)
|
||||
{
|
||||
var contents = File.ReadAllText(file);
|
||||
var idx = contents.IndexOf(startToken);
|
||||
while (idx != -1)
|
||||
{
|
||||
idx += startToken.Length + 1;
|
||||
int braces = 1;
|
||||
int start = idx;
|
||||
while (idx < contents.Length && braces != 0)
|
||||
{
|
||||
if (contents[idx] == '(')
|
||||
braces++;
|
||||
if (contents[idx] == ')')
|
||||
braces--;
|
||||
idx++;
|
||||
}
|
||||
if (idx == contents.Length)
|
||||
break;
|
||||
var inside = contents.Substring(start, idx - start - 1);
|
||||
var textStart = inside.IndexOf(textToken);
|
||||
if (textStart != -1)
|
||||
{
|
||||
textStart += textToken.Length;
|
||||
var textEnd = textStart;
|
||||
while (textEnd < inside.Length && inside[textEnd] != '\"')
|
||||
{
|
||||
if (inside[textEnd] == '\\')
|
||||
textEnd++;
|
||||
textEnd++;
|
||||
}
|
||||
var id = inside.Substring(textStart, textEnd - textStart);
|
||||
textStart = inside.Length > textEnd + 2 ? inside.IndexOf(textToken, textEnd + 2) : -1;
|
||||
string value = null;
|
||||
if (textStart != -1)
|
||||
{
|
||||
textStart += textToken.Length;
|
||||
textEnd = textStart;
|
||||
while (textEnd < inside.Length && inside[textEnd] != '\"')
|
||||
{
|
||||
if (inside[textEnd] == '\\')
|
||||
textEnd++;
|
||||
textEnd++;
|
||||
}
|
||||
value = inside.Substring(textStart, textEnd - textStart);
|
||||
}
|
||||
|
||||
if (!allKeys.Contains(id))
|
||||
newKeys[id] = value;
|
||||
}
|
||||
|
||||
idx = contents.IndexOf(startToken, idx);
|
||||
}
|
||||
}
|
||||
|
||||
private static void FindNewKeysJson(Dictionary<string, string> newKeys, HashSet<string> allKeys, JToken token)
|
||||
{
|
||||
if (token is JObject o)
|
||||
{
|
||||
foreach (var p in o)
|
||||
{
|
||||
if (string.Equals(p.Key, "Id", StringComparison.Ordinal) && p.Value is JValue i && i.Value is string id && !allKeys.Contains(id))
|
||||
{
|
||||
var count = o.Properties().Count();
|
||||
if (count == 1)
|
||||
{
|
||||
newKeys[id] = null;
|
||||
return;
|
||||
}
|
||||
if (count == 2)
|
||||
{
|
||||
var v = o.Property("Value")?.Value as JValue;
|
||||
if (v?.Value is string value)
|
||||
{
|
||||
newKeys[id] = value;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
FindNewKeysJson(newKeys, allKeys, p.Value);
|
||||
}
|
||||
}
|
||||
else if (token is JArray a)
|
||||
{
|
||||
foreach (var p in a)
|
||||
{
|
||||
FindNewKeysJson(newKeys, allKeys, p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void FindNewKeysJson(string file, Dictionary<string, string> newKeys, HashSet<string> allKeys)
|
||||
{
|
||||
using (var reader = new StreamReader(file))
|
||||
using (var jsonReader = new JsonTextReader(reader))
|
||||
{
|
||||
var token = JToken.ReadFrom(jsonReader);
|
||||
FindNewKeysJson(newKeys, allKeys, token);
|
||||
}
|
||||
}
|
||||
|
||||
private void AddNewKeys(Dictionary<string, string> newKeys, int filesCount, IEnumerable<IGrouping<string, LocalizedStringTable>> locales, Dictionary<LocalizedStringTable, Dictionary<string, string[]>> tableEntries)
|
||||
{
|
||||
Editor.Log($"Found {newKeys.Count} new localized strings in {filesCount} files");
|
||||
if (newKeys.Count == 0)
|
||||
return;
|
||||
foreach (var e in newKeys)
|
||||
Editor.Log(e.Key + (e.Value != null ? " = " + e.Value : string.Empty));
|
||||
foreach (var locale in locales)
|
||||
{
|
||||
var table = locale.First();
|
||||
var entries = tableEntries[table];
|
||||
if (table.Locale == "en")
|
||||
{
|
||||
foreach (var e in newKeys)
|
||||
entries[e.Key] = new[] { e.Value };
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var e in newKeys)
|
||||
entries[e.Key] = new[] { string.Empty };
|
||||
}
|
||||
table.Entries = entries;
|
||||
table.Save();
|
||||
}
|
||||
RebuildLayout();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -154,9 +154,20 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
if (i != 0 && spacing > 0f)
|
||||
{
|
||||
if (layout.Children.Count > 0 && layout.Children[layout.Children.Count - 1] is PropertiesListElement propertiesListElement)
|
||||
{
|
||||
if (propertiesListElement.Labels.Count > 0)
|
||||
{
|
||||
var label = propertiesListElement.Labels[propertiesListElement.Labels.Count - 1];
|
||||
var margin = label.Margin;
|
||||
margin.Bottom += spacing;
|
||||
label.Margin = margin;
|
||||
}
|
||||
propertiesListElement.Space(spacing);
|
||||
}
|
||||
else
|
||||
{
|
||||
layout.Space(spacing);
|
||||
}
|
||||
}
|
||||
|
||||
var overrideEditor = overrideEditorType != null ? (CustomEditor)Activator.CreateInstance(overrideEditorType) : null;
|
||||
|
||||
164
Source/Editor/CustomEditors/Editors/CultureInfoEditor.cs
Normal file
164
Source/Editor/CustomEditors/Editors/CultureInfoEditor.cs
Normal file
@@ -0,0 +1,164 @@
|
||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using FlaxEditor.GUI;
|
||||
using FlaxEditor.GUI.ContextMenu;
|
||||
using FlaxEditor.GUI.Tree;
|
||||
using FlaxEditor.Utilities;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
|
||||
namespace FlaxEditor.CustomEditors.Editors
|
||||
{
|
||||
/// <summary>
|
||||
/// Default implementation of the inspector used to edit <see cref="CultureInfo"/> value type properties. Supports editing property of <see cref="string"/> type (as culture name).
|
||||
/// </summary>
|
||||
[CustomEditor(typeof(CultureInfo)), DefaultEditor]
|
||||
internal class CultureInfoEditor : CustomEditor
|
||||
{
|
||||
private ClickableLabel _label;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override DisplayStyle Style => DisplayStyle.Inline;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Initialize(LayoutElementsContainer layout)
|
||||
{
|
||||
_label = layout.ClickableLabel(GetName(Culture)).CustomControl;
|
||||
_label.RightClick += ShowPicker;
|
||||
var button = new Button
|
||||
{
|
||||
Width = 16.0f,
|
||||
Text = "...",
|
||||
Parent = _label,
|
||||
};
|
||||
button.SetAnchorPreset(AnchorPresets.MiddleRight, false, true);
|
||||
button.Clicked += ShowPicker;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Refresh()
|
||||
{
|
||||
base.Refresh();
|
||||
|
||||
_label.Text = GetName(Culture);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Deinitialize()
|
||||
{
|
||||
_label = null;
|
||||
|
||||
base.Deinitialize();
|
||||
}
|
||||
|
||||
private CultureInfo Culture
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Values[0] is CultureInfo asCultureInfo)
|
||||
return asCultureInfo;
|
||||
if (Values[0] is string asString)
|
||||
return new CultureInfo(asString);
|
||||
return null;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (Values[0] is CultureInfo)
|
||||
SetValue(value);
|
||||
else if (Values[0] is string)
|
||||
SetValue(value.Name);
|
||||
}
|
||||
}
|
||||
|
||||
private class CultureInfoComparer : IComparer<CultureInfo>
|
||||
{
|
||||
public int Compare(CultureInfo a, CultureInfo b)
|
||||
{
|
||||
return string.Compare(a.Name, b.Name, StringComparison.Ordinal);
|
||||
}
|
||||
}
|
||||
|
||||
private static void UpdateFilter(TreeNode node, string filterText)
|
||||
{
|
||||
// Update children
|
||||
bool isAnyChildVisible = false;
|
||||
for (int i = 0; i < node.Children.Count; i++)
|
||||
{
|
||||
if (node.Children[i] is TreeNode child)
|
||||
{
|
||||
UpdateFilter(child, filterText);
|
||||
isAnyChildVisible |= child.Visible;
|
||||
}
|
||||
}
|
||||
|
||||
// Update itself
|
||||
bool noFilter = string.IsNullOrWhiteSpace(filterText);
|
||||
bool isThisVisible = noFilter || QueryFilterHelper.Match(filterText, node.Text);
|
||||
bool isExpanded = isAnyChildVisible;
|
||||
if (isExpanded)
|
||||
node.Expand(true);
|
||||
else
|
||||
node.Collapse(true);
|
||||
node.Visible = isThisVisible | isAnyChildVisible;
|
||||
}
|
||||
|
||||
private void ShowPicker()
|
||||
{
|
||||
var menu = CreatePicker(Culture, value => { Culture = value; });
|
||||
menu.Show(_label, new Vector2(0, _label.Height));
|
||||
}
|
||||
|
||||
internal static ContextMenuBase CreatePicker(CultureInfo value, Action<CultureInfo> changed)
|
||||
{
|
||||
var menu = Utilities.Utils.CreateSearchPopup(out var searchBox, out var tree);
|
||||
tree.Margin = new Margin(-16.0f, 0.0f, -16.0f, -0.0f); // Hide root node
|
||||
var root = tree.AddChild<TreeNode>();
|
||||
var cultures = CultureInfo.GetCultures(CultureTypes.AllCultures);
|
||||
Array.Sort(cultures, 1, cultures.Length - 2, new CultureInfoComparer()); // at 0 there is Invariant Culture
|
||||
var lcidToNode = new Dictionary<int, ContainerControl>();
|
||||
for (var i = 0; i < cultures.Length; i++)
|
||||
{
|
||||
var culture = cultures[i];
|
||||
var node = new TreeNode
|
||||
{
|
||||
Tag = culture,
|
||||
Text = GetName(culture),
|
||||
};
|
||||
if (!lcidToNode.TryGetValue(culture.Parent.LCID, out ContainerControl parent))
|
||||
parent = root;
|
||||
node.Parent = parent;
|
||||
lcidToNode[culture.LCID] = node;
|
||||
}
|
||||
if (value != null)
|
||||
tree.Select((TreeNode)lcidToNode[value.LCID]);
|
||||
tree.SelectedChanged += delegate(List<TreeNode> before, List<TreeNode> after)
|
||||
{
|
||||
if (after.Count == 1)
|
||||
{
|
||||
menu.Hide();
|
||||
changed((CultureInfo)after[0].Tag);
|
||||
}
|
||||
};
|
||||
searchBox.TextChanged += delegate
|
||||
{
|
||||
if (tree.IsLayoutLocked)
|
||||
return;
|
||||
root.LockChildrenRecursive();
|
||||
var query = searchBox.Text;
|
||||
UpdateFilter(root, query);
|
||||
root.UnlockChildrenRecursive();
|
||||
menu.PerformLayout();
|
||||
};
|
||||
root.ExpandAll(true);
|
||||
return menu;
|
||||
}
|
||||
|
||||
internal static string GetName(CultureInfo value)
|
||||
{
|
||||
return value != null ? string.Format("{0} - {1}", value.Name, value.EnglishName) : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -61,7 +61,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
var keyType = _editor.Values.Type.GetGenericArguments()[0];
|
||||
if (keyType == typeof(string) || keyType.IsPrimitive)
|
||||
{
|
||||
var popup = RenamePopup.Show(Parent, Bounds, Text, false);
|
||||
var popup = RenamePopup.Show(Parent, Rectangle.Margin(Bounds, Margin), Text, false);
|
||||
popup.Validate += (renamePopup, value) =>
|
||||
{
|
||||
object newKey;
|
||||
@@ -86,7 +86,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
}
|
||||
else if (keyType.IsEnum)
|
||||
{
|
||||
var popup = RenamePopup.Show(Parent, Bounds, Text, false);
|
||||
var popup = RenamePopup.Show(Parent, Rectangle.Margin(Bounds, Margin), Text, false);
|
||||
var picker = new EnumComboBox(keyType)
|
||||
{
|
||||
AnchorPreset = AnchorPresets.StretchAll,
|
||||
@@ -220,9 +220,20 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
if (i != 0 && spacing > 0f)
|
||||
{
|
||||
if (layout.Children.Count > 0 && layout.Children[layout.Children.Count - 1] is PropertiesListElement propertiesListElement)
|
||||
{
|
||||
if (propertiesListElement.Labels.Count > 0)
|
||||
{
|
||||
var label = propertiesListElement.Labels[propertiesListElement.Labels.Count - 1];
|
||||
var margin = label.Margin;
|
||||
margin.Bottom += spacing;
|
||||
label.Margin = margin;
|
||||
}
|
||||
propertiesListElement.Space(spacing);
|
||||
}
|
||||
else
|
||||
{
|
||||
layout.Space(spacing);
|
||||
}
|
||||
}
|
||||
|
||||
var key = keys.ElementAt(i);
|
||||
|
||||
@@ -9,7 +9,7 @@ using FlaxEngine;
|
||||
namespace FlaxEditor.CustomEditors.Editors
|
||||
{
|
||||
/// <summary>
|
||||
/// Default implementation of the inspector used to edit float value type properties.
|
||||
/// Default implementation of the inspector used to edit enum value type properties.
|
||||
/// </summary>
|
||||
[CustomEditor(typeof(Enum)), DefaultEditor]
|
||||
public class EnumEditor : CustomEditor
|
||||
|
||||
@@ -214,6 +214,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
public ScriptMemberInfo Target;
|
||||
public ScriptMemberInfo Source;
|
||||
public PropertiesListElement PropertiesList;
|
||||
public GroupElement Group;
|
||||
public bool Invert;
|
||||
public int LabelIndex;
|
||||
|
||||
@@ -257,15 +258,15 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
for (int i = 0; i < properties.Length; i++)
|
||||
{
|
||||
var p = properties[i];
|
||||
var attributes = p.GetAttributes(true);
|
||||
var showInEditor = attributes.Any(x => x is ShowInEditorAttribute);
|
||||
|
||||
// Skip properties without getter or setter
|
||||
if (!p.HasGet || !p.HasSet)
|
||||
if (!p.HasGet || (!p.HasSet && !showInEditor))
|
||||
continue;
|
||||
|
||||
var attributes = p.GetAttributes(true);
|
||||
|
||||
|
||||
// Skip hidden fields, handle special attributes
|
||||
if ((!p.IsPublic && !attributes.Any(x => x is ShowInEditorAttribute)) || attributes.Any(x => x is HideInEditorAttribute))
|
||||
if ((!p.IsPublic && !showInEditor) || attributes.Any(x => x is HideInEditorAttribute))
|
||||
continue;
|
||||
|
||||
items.Add(new ItemInfo(p, attributes));
|
||||
@@ -379,26 +380,22 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
}
|
||||
}
|
||||
}
|
||||
if (item.VisibleIf != null)
|
||||
if (item.VisibleIf != null && itemLayout.Children.Count > 0)
|
||||
{
|
||||
PropertiesListElement list;
|
||||
if (itemLayout.Children.Count > 0 && itemLayout.Children[itemLayout.Children.Count - 1] is PropertiesListElement list1)
|
||||
{
|
||||
PropertiesListElement list = null;
|
||||
GroupElement group = null;
|
||||
if (itemLayout.Children[itemLayout.Children.Count - 1] is PropertiesListElement list1)
|
||||
list = list1;
|
||||
}
|
||||
else if (itemLayout.Children[itemLayout.Children.Count - 1] is GroupElement group1)
|
||||
group = group1;
|
||||
else
|
||||
{
|
||||
// TODO: support inlined objects hiding?
|
||||
return;
|
||||
}
|
||||
|
||||
// Get source member used to check rule
|
||||
var sourceMember = GetVisibleIfSource(item.Info.DeclaringType, item.VisibleIf);
|
||||
if (sourceMember == ScriptType.Null)
|
||||
return;
|
||||
|
||||
// Find the target control to show/hide
|
||||
|
||||
// Resize cache
|
||||
if (_visibleIfCaches == null)
|
||||
_visibleIfCaches = new VisibleIfCache[8];
|
||||
@@ -414,6 +411,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
Target = item.Info,
|
||||
Source = sourceMember,
|
||||
PropertiesList = list,
|
||||
Group = group,
|
||||
LabelIndex = labelIndex,
|
||||
Invert = item.VisibleIf.Invert,
|
||||
};
|
||||
@@ -569,8 +567,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
{
|
||||
for (int i = 0; i < _visibleIfCaches.Length; i++)
|
||||
{
|
||||
var c = _visibleIfCaches[i];
|
||||
|
||||
ref var c = ref _visibleIfCaches[i];
|
||||
if (c.Target == ScriptMemberInfo.Null)
|
||||
break;
|
||||
|
||||
@@ -586,7 +583,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
}
|
||||
|
||||
// Apply the visibility (note: there may be no label)
|
||||
if (c.LabelIndex != -1 && c.PropertiesList.Labels.Count > c.LabelIndex)
|
||||
if (c.LabelIndex != -1 && c.PropertiesList != null && c.PropertiesList.Labels.Count > c.LabelIndex)
|
||||
{
|
||||
var label = c.PropertiesList.Labels[c.LabelIndex];
|
||||
label.Visible = visible;
|
||||
@@ -599,6 +596,10 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
child.Visible = visible;
|
||||
}
|
||||
}
|
||||
if (c.Group != null)
|
||||
{
|
||||
c.Group.Panel.Visible = visible;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
234
Source/Editor/CustomEditors/Editors/LocalizedStringEditor.cs
Normal file
234
Source/Editor/CustomEditors/Editors/LocalizedStringEditor.cs
Normal file
@@ -0,0 +1,234 @@
|
||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FlaxEditor.Content.Settings;
|
||||
using FlaxEditor.CustomEditors.Elements;
|
||||
using FlaxEditor.GUI.Tree;
|
||||
using FlaxEditor.Scripting;
|
||||
using FlaxEditor.Utilities;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
using Utils = FlaxEditor.Utilities.Utils;
|
||||
|
||||
namespace FlaxEditor.CustomEditors.Editors
|
||||
{
|
||||
/// <summary>
|
||||
/// Default implementation of the inspector used to edit localized string properties.
|
||||
/// </summary>
|
||||
[CustomEditor(typeof(LocalizedString)), DefaultEditor]
|
||||
public sealed class LocalizedStringEditor : GenericEditor
|
||||
{
|
||||
private TextBoxElement _idElement, _valueElement;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override DisplayStyle Style => DisplayStyle.Inline;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Initialize(LayoutElementsContainer layout)
|
||||
{
|
||||
base.Initialize(layout);
|
||||
|
||||
if (layout.Children.Count == 0)
|
||||
return;
|
||||
var propList = layout.Children[layout.Children.Count - 1] as PropertiesListElement;
|
||||
if (propList == null || propList.Children.Count != 2)
|
||||
return;
|
||||
var idElement = propList.Children[0] as TextBoxElement;
|
||||
var valueElement = propList.Children[1] as TextBoxElement;
|
||||
if (idElement == null || valueElement == null)
|
||||
return;
|
||||
_idElement = idElement;
|
||||
_valueElement = valueElement;
|
||||
|
||||
var attributes = Values.GetAttributes();
|
||||
var multiLine = attributes?.FirstOrDefault(x => x is MultilineTextAttribute);
|
||||
if (multiLine != null)
|
||||
{
|
||||
valueElement.TextBox.IsMultiline = true;
|
||||
valueElement.TextBox.Height *= 3;
|
||||
}
|
||||
|
||||
var selectString = new Button
|
||||
{
|
||||
Width = 16.0f,
|
||||
Text = "...",
|
||||
TooltipText = "Select localized text from Localization Settings...",
|
||||
Parent = idElement.TextBox,
|
||||
};
|
||||
selectString.SetAnchorPreset(AnchorPresets.MiddleRight, false, true);
|
||||
selectString.ButtonClicked += OnSelectStringClicked;
|
||||
|
||||
var addString = new Button
|
||||
{
|
||||
Width = 16.0f,
|
||||
Text = "+",
|
||||
TooltipText = "Add new localized text to Localization Settings (all used locales)",
|
||||
Parent = _valueElement.TextBox,
|
||||
Enabled = IsSingleObject,
|
||||
};
|
||||
addString.SetAnchorPreset(AnchorPresets.MiddleRight, false, true);
|
||||
addString.ButtonClicked += OnAddStringClicked;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
internal override void RefreshInternal()
|
||||
{
|
||||
base.RefreshInternal();
|
||||
|
||||
if (_valueElement != null)
|
||||
{
|
||||
_valueElement.TextBox.WatermarkText = Localization.GetString(_idElement.Text);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Deinitialize()
|
||||
{
|
||||
base.Deinitialize();
|
||||
|
||||
_idElement = null;
|
||||
_valueElement = null;
|
||||
}
|
||||
|
||||
private void OnSelectStringClicked(Button button)
|
||||
{
|
||||
var settings = GameSettings.Load<LocalizationSettings>();
|
||||
if (settings?.LocalizedStringTables == null || settings.LocalizedStringTables.Length == 0)
|
||||
{
|
||||
MessageBox.Show("No valid localization settings setup.");
|
||||
return;
|
||||
}
|
||||
Profiler.BeginEvent("LocalizedStringEditor.OnSelectStringClicked");
|
||||
var allKeys = new HashSet<string>();
|
||||
for (int i = 0; i < settings.LocalizedStringTables.Length; i++)
|
||||
{
|
||||
var table = settings.LocalizedStringTables[i];
|
||||
if (table && !table.WaitForLoaded())
|
||||
{
|
||||
var entries = table.Entries;
|
||||
foreach (var e in entries)
|
||||
allKeys.Add(e.Key);
|
||||
}
|
||||
}
|
||||
var allKeysSorted = allKeys.ToList();
|
||||
allKeysSorted.Sort();
|
||||
var value = _idElement?.TextBox.Text;
|
||||
var menu = Utils.CreateSearchPopup(out var searchBox, out var tree);
|
||||
var idToNode = new TreeNode[allKeysSorted.Count];
|
||||
for (var i = 0; i < allKeysSorted.Count; i++)
|
||||
{
|
||||
var key = allKeysSorted[i];
|
||||
var node = new TreeNode
|
||||
{
|
||||
Text = key,
|
||||
TooltipText = Localization.GetString(key),
|
||||
Parent = tree,
|
||||
};
|
||||
if (key == value)
|
||||
tree.Select(node);
|
||||
idToNode[i] = node;
|
||||
}
|
||||
tree.SelectedChanged += delegate(List<TreeNode> before, List<TreeNode> after)
|
||||
{
|
||||
if (after.Count == 1)
|
||||
{
|
||||
menu.Hide();
|
||||
_idElement.TextBox.SetTextAsUser(after[0].Text);
|
||||
}
|
||||
};
|
||||
searchBox.TextChanged += delegate
|
||||
{
|
||||
if (tree.IsLayoutLocked)
|
||||
return;
|
||||
tree.LockChildrenRecursive();
|
||||
var query = searchBox.Text;
|
||||
for (int i = 0; i < idToNode.Length; i++)
|
||||
{
|
||||
var node = idToNode[i];
|
||||
node.Visible = string.IsNullOrWhiteSpace(query) || QueryFilterHelper.Match(query, node.Text);
|
||||
}
|
||||
tree.UnlockChildrenRecursive();
|
||||
menu.PerformLayout();
|
||||
};
|
||||
menu.Show(button, new Vector2(0, button.Height));
|
||||
Profiler.EndEvent();
|
||||
}
|
||||
|
||||
private void OnAddStringClicked(Button button)
|
||||
{
|
||||
var settings = GameSettings.Load<LocalizationSettings>();
|
||||
if (settings?.LocalizedStringTables == null || settings.LocalizedStringTables.Length == 0)
|
||||
{
|
||||
MessageBox.Show("No valid localization settings setup.");
|
||||
return;
|
||||
}
|
||||
Profiler.BeginEvent("LocalizedStringEditor.OnAddStringClicked");
|
||||
var allKeys = new HashSet<string>();
|
||||
for (int i = 0; i < settings.LocalizedStringTables.Length; i++)
|
||||
{
|
||||
var table = settings.LocalizedStringTables[i];
|
||||
if (table && !table.WaitForLoaded())
|
||||
{
|
||||
var entries = table.Entries;
|
||||
foreach (var e in entries)
|
||||
allKeys.Add(e.Key);
|
||||
}
|
||||
}
|
||||
_valueElement.TextBox.SetTextAsUser(null);
|
||||
string newKey = null;
|
||||
if (string.IsNullOrEmpty(_idElement.Text))
|
||||
{
|
||||
CustomEditor customEditor = this;
|
||||
while (customEditor?.Values != null)
|
||||
{
|
||||
if (customEditor.Values.Info != ScriptMemberInfo.Null)
|
||||
if (newKey == null)
|
||||
newKey = customEditor.Values.Info.Name;
|
||||
else
|
||||
newKey = customEditor.Values.Info.Name + '.' + newKey;
|
||||
else if (customEditor.Values[0] is SceneObject sceneObject)
|
||||
if (newKey == null)
|
||||
newKey = sceneObject.GetNamePath('.');
|
||||
else
|
||||
newKey = sceneObject.GetNamePath('.') + '.' + newKey;
|
||||
else
|
||||
break;
|
||||
customEditor = customEditor.ParentEditor;
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(newKey))
|
||||
newKey = Guid.NewGuid().ToString("N");
|
||||
}
|
||||
else
|
||||
{
|
||||
newKey = _idElement.Text;
|
||||
}
|
||||
if (allKeys.Contains(newKey))
|
||||
{
|
||||
Profiler.EndEvent();
|
||||
if (_idElement.Text != newKey)
|
||||
_idElement.TextBox.SetTextAsUser(newKey);
|
||||
else
|
||||
MessageBox.Show("Already added.");
|
||||
return;
|
||||
}
|
||||
var newValue = _valueElement.Text;
|
||||
Editor.Log(newKey + (newValue != null ? " = " + newValue : string.Empty));
|
||||
var locales = settings.LocalizedStringTables.GroupBy(x => x.Locale);
|
||||
foreach (var locale in locales)
|
||||
{
|
||||
var table = locale.First();
|
||||
var entries = table.Entries;
|
||||
if (table.Locale == "en")
|
||||
entries[newKey] = new[] { newValue };
|
||||
else
|
||||
entries[newKey] = new[] { string.Empty };
|
||||
table.Entries = entries;
|
||||
table.Save();
|
||||
}
|
||||
_idElement.TextBox.SetTextAsUser(newKey);
|
||||
Profiler.EndEvent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,6 @@
|
||||
using System;
|
||||
using FlaxEditor.GUI;
|
||||
using FlaxEditor.Scripting;
|
||||
using FlaxEngine;
|
||||
|
||||
namespace FlaxEditor.CustomEditors.Editors
|
||||
{
|
||||
|
||||
@@ -5,15 +5,15 @@ using FlaxEngine.GUI;
|
||||
namespace FlaxEditor.CustomEditors.Elements
|
||||
{
|
||||
/// <summary>
|
||||
/// The vertical panel element.
|
||||
/// The horizontal panel element.
|
||||
/// </summary>
|
||||
/// <seealso cref="FlaxEditor.CustomEditors.LayoutElement" />
|
||||
public class VerticalPanelElement : LayoutElementsContainer
|
||||
public class HorizontalPanelElement : LayoutElementsContainer
|
||||
{
|
||||
/// <summary>
|
||||
/// The panel.
|
||||
/// </summary>
|
||||
public readonly VerticalPanel Panel = new VerticalPanel();
|
||||
public readonly HorizontalPanel Panel = new HorizontalPanel();
|
||||
|
||||
/// <inheritdoc />
|
||||
public override ContainerControl ContainerControl => Panel;
|
||||
|
||||
@@ -5,15 +5,15 @@ using FlaxEngine.GUI;
|
||||
namespace FlaxEditor.CustomEditors.Elements
|
||||
{
|
||||
/// <summary>
|
||||
/// The horizontal panel element.
|
||||
/// The vertical panel element.
|
||||
/// </summary>
|
||||
/// <seealso cref="FlaxEditor.CustomEditors.LayoutElement" />
|
||||
public class HorizontalPanelElement : LayoutElementsContainer
|
||||
public class VerticalPanelElement : LayoutElementsContainer
|
||||
{
|
||||
/// <summary>
|
||||
/// The panel.
|
||||
/// </summary>
|
||||
public readonly HorizontalPanel Panel = new HorizontalPanel();
|
||||
public readonly VerticalPanel Panel = new VerticalPanel();
|
||||
|
||||
/// <inheritdoc />
|
||||
public override ContainerControl ContainerControl => Panel;
|
||||
|
||||
@@ -112,7 +112,7 @@ namespace FlaxEditor.CustomEditors
|
||||
OnAddElement(element);
|
||||
return element;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Adds new horizontal panel element.
|
||||
/// </summary>
|
||||
@@ -690,6 +690,17 @@ namespace FlaxEditor.CustomEditors
|
||||
return element;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds custom element to the layout.
|
||||
/// </summary>
|
||||
/// <param name="element">The element.</param>
|
||||
public void AddElement(LayoutElement element)
|
||||
{
|
||||
if (element == null)
|
||||
throw new ArgumentNullException();
|
||||
OnAddElement(element);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when element is added to the layout.
|
||||
/// </summary>
|
||||
|
||||
@@ -220,7 +220,7 @@ namespace FlaxEditor
|
||||
GameProject = ProjectInfo.Load(Internal_GetProjectPath());
|
||||
|
||||
Icons = new EditorIcons();
|
||||
Icons.GetIcons();
|
||||
Icons.LoadIcons();
|
||||
|
||||
// Create common editor modules
|
||||
RegisterModule(Options = new OptionsModule(this));
|
||||
@@ -878,10 +878,12 @@ namespace FlaxEditor
|
||||
/// Checks if can import asset with the given extension.
|
||||
/// </summary>
|
||||
/// <param name="extension">The file extension.</param>
|
||||
/// <param name="outputExtension">The output file extension (flax, json, etc.).</param>
|
||||
/// <returns>True if can import files with given extension, otherwise false.</returns>
|
||||
public static bool CanImport(string extension)
|
||||
public static bool CanImport(string extension, out string outputExtension)
|
||||
{
|
||||
return Internal_CanImport(extension);
|
||||
outputExtension = Internal_CanImport(extension);
|
||||
return outputExtension != null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1183,6 +1185,8 @@ namespace FlaxEditor
|
||||
var win = Windows.GameWin.Root;
|
||||
if (win?.RootWindow is WindowRootControl root && root.Window && root.Window.IsFocused)
|
||||
{
|
||||
if (StateMachine.IsPlayMode && StateMachine.PlayingState.IsPaused)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1369,7 +1373,7 @@ namespace FlaxEditor
|
||||
internal static extern bool Internal_CreateVisualScript(string outputPath, string baseTypename);
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||
internal static extern bool Internal_CanImport(string extension);
|
||||
internal static extern string Internal_CanImport(string extension);
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||
internal static extern bool Internal_CanExport(string path);
|
||||
|
||||
@@ -16,102 +16,124 @@ namespace FlaxEditor
|
||||
[HideInEditor]
|
||||
public sealed class EditorIcons
|
||||
{
|
||||
public SpriteHandle FolderClosed12;
|
||||
public SpriteHandle FolderOpened12;
|
||||
// 12px
|
||||
public SpriteHandle DragBar12;
|
||||
public SpriteHandle ArrowDown12;
|
||||
public SpriteHandle ArrowRight12;
|
||||
public SpriteHandle Search12;
|
||||
public SpriteHandle WindowDrag12;
|
||||
public SpriteHandle CheckBoxIntermediate12;
|
||||
public SpriteHandle ArrowRight12;
|
||||
public SpriteHandle Settings12;
|
||||
public SpriteHandle Cross12;
|
||||
public SpriteHandle CheckBoxIntermediate12;
|
||||
public SpriteHandle CheckBoxTick12;
|
||||
public SpriteHandle StatusBarSizeGrip12;
|
||||
public SpriteHandle ArrowDown12;
|
||||
|
||||
public SpriteHandle ArrowRightBorder16;
|
||||
public SpriteHandle World16;
|
||||
public SpriteHandle ScaleStep16;
|
||||
public SpriteHandle RotateStep16;
|
||||
public SpriteHandle Grid16;
|
||||
public SpriteHandle Translate16;
|
||||
public SpriteHandle Rotate16;
|
||||
public SpriteHandle Scale16;
|
||||
public SpriteHandle Link16;
|
||||
public SpriteHandle Docs16;
|
||||
|
||||
public SpriteHandle Save32;
|
||||
public SpriteHandle Undo32;
|
||||
public SpriteHandle Redo32;
|
||||
// 32px
|
||||
public SpriteHandle Scalar32;
|
||||
public SpriteHandle Translate32;
|
||||
public SpriteHandle Rotate32;
|
||||
public SpriteHandle Scale32;
|
||||
public SpriteHandle Play32;
|
||||
public SpriteHandle Pause32;
|
||||
public SpriteHandle Step32;
|
||||
public SpriteHandle Stop32;
|
||||
public SpriteHandle PageScale32;
|
||||
public SpriteHandle Bone32;
|
||||
public SpriteHandle Docs32;
|
||||
public SpriteHandle Import32;
|
||||
public SpriteHandle AddDoc32;
|
||||
public SpriteHandle RemoveDoc32;
|
||||
public SpriteHandle BracketsSlash32;
|
||||
public SpriteHandle Find32;
|
||||
public SpriteHandle Reload32;
|
||||
public SpriteHandle ArrowLeft32;
|
||||
public SpriteHandle ArrowRight32;
|
||||
public SpriteHandle ArrowDown32;
|
||||
public SpriteHandle ArrowUp32;
|
||||
public SpriteHandle Error32;
|
||||
public SpriteHandle Warning32;
|
||||
public SpriteHandle Info32;
|
||||
public SpriteHandle UV32;
|
||||
public SpriteHandle Image32;
|
||||
public SpriteHandle Grid32;
|
||||
public SpriteHandle Flax32;
|
||||
public SpriteHandle RotateSnap32;
|
||||
public SpriteHandle ScaleSnap32;
|
||||
public SpriteHandle Globe32;
|
||||
public SpriteHandle CamSpeed32;
|
||||
public SpriteHandle Link32;
|
||||
public SpriteHandle Next32;
|
||||
public SpriteHandle Camera32;
|
||||
public SpriteHandle Build32;
|
||||
public SpriteHandle Add32;
|
||||
public SpriteHandle Left32;
|
||||
public SpriteHandle Right32;
|
||||
public SpriteHandle Up32;
|
||||
public SpriteHandle Down32;
|
||||
public SpriteHandle FolderClosed32;
|
||||
public SpriteHandle FolderOpen32;
|
||||
|
||||
public SpriteHandle Add48;
|
||||
public SpriteHandle Paint48;
|
||||
public SpriteHandle Foliage48;
|
||||
public SpriteHandle Mountain48;
|
||||
// Visject
|
||||
public SpriteHandle VisjectBoxOpen32;
|
||||
public SpriteHandle VisjectBoxClosed32;
|
||||
public SpriteHandle VisjectArrowOpen32;
|
||||
public SpriteHandle VisjectArrowClosed32;
|
||||
|
||||
public SpriteHandle Plugin64;
|
||||
public SpriteHandle Document64;
|
||||
public SpriteHandle CSharpScript64;
|
||||
public SpriteHandle CppScript64;
|
||||
// 64px
|
||||
public SpriteHandle Flax64;
|
||||
public SpriteHandle Save64;
|
||||
public SpriteHandle Play64;
|
||||
public SpriteHandle Stop64;
|
||||
public SpriteHandle Pause64;
|
||||
public SpriteHandle Skip64;
|
||||
public SpriteHandle Info64;
|
||||
public SpriteHandle Error64;
|
||||
public SpriteHandle Warning64;
|
||||
public SpriteHandle AddFile64;
|
||||
public SpriteHandle DeleteFile64;
|
||||
public SpriteHandle Import64;
|
||||
public SpriteHandle Left64;
|
||||
public SpriteHandle Right64;
|
||||
public SpriteHandle Up64;
|
||||
public SpriteHandle Down64;
|
||||
public SpriteHandle Undo64;
|
||||
public SpriteHandle Redo64;
|
||||
public SpriteHandle Translate64;
|
||||
public SpriteHandle Rotate64;
|
||||
public SpriteHandle Scale64;
|
||||
public SpriteHandle Refresh64;
|
||||
public SpriteHandle Shift64;
|
||||
public SpriteHandle Code64;
|
||||
public SpriteHandle Folder64;
|
||||
public SpriteHandle Scene64;
|
||||
public SpriteHandle CodeScript64;
|
||||
public SpriteHandle CenterView64;
|
||||
public SpriteHandle Image64;
|
||||
public SpriteHandle Camera64;
|
||||
public SpriteHandle Docs64;
|
||||
public SpriteHandle Search64;
|
||||
public SpriteHandle Bone64;
|
||||
public SpriteHandle Link64;
|
||||
public SpriteHandle Build64;
|
||||
public SpriteHandle Add64;
|
||||
|
||||
public SpriteHandle Logo128;
|
||||
// 96px
|
||||
public SpriteHandle Toolbox96;
|
||||
public SpriteHandle Paint96;
|
||||
public SpriteHandle Foliage96;
|
||||
public SpriteHandle Terrain96;
|
||||
|
||||
public SpriteHandle VisjectBoxOpen;
|
||||
public SpriteHandle VisjectBoxClose;
|
||||
public SpriteHandle VisjectArrowOpen;
|
||||
public SpriteHandle VisjectArrowClose;
|
||||
// 128px
|
||||
public SpriteHandle AndroidSettings128;
|
||||
public SpriteHandle PlaystationSettings128;
|
||||
public SpriteHandle InputSettings128;
|
||||
public SpriteHandle PhysicsSettings128;
|
||||
public SpriteHandle CSharpScript128;
|
||||
public SpriteHandle Folder128;
|
||||
public SpriteHandle WindowsIcon128;
|
||||
public SpriteHandle LinuxIcon128;
|
||||
public SpriteHandle UWPSettings128;
|
||||
public SpriteHandle XBOXSettings128;
|
||||
public SpriteHandle LayersTagsSettings128;
|
||||
public SpriteHandle GraphicsSettings128;
|
||||
public SpriteHandle CPPScript128;
|
||||
public SpriteHandle Plugin128;
|
||||
public SpriteHandle XBoxScarletIcon128;
|
||||
public SpriteHandle AssetShadow128;
|
||||
public SpriteHandle WindowsSettings128;
|
||||
public SpriteHandle TimeSettings128;
|
||||
public SpriteHandle GameSettings128;
|
||||
public SpriteHandle VisualScript128;
|
||||
public SpriteHandle Document128;
|
||||
public SpriteHandle XBoxOne128;
|
||||
public SpriteHandle UWPStore128;
|
||||
public SpriteHandle ColorWheel128;
|
||||
public SpriteHandle LinuxSettings128;
|
||||
public SpriteHandle NavigationSettings128;
|
||||
public SpriteHandle AudioSettings128;
|
||||
public SpriteHandle BuildSettings128;
|
||||
public SpriteHandle Scene128;
|
||||
public SpriteHandle AndroidIcon128;
|
||||
public SpriteHandle PS4Icon128;
|
||||
public SpriteHandle FlaxLogo128;
|
||||
|
||||
public SpriteHandle AssetShadow;
|
||||
public SpriteHandle ColorWheel;
|
||||
public SpriteHandle Windows;
|
||||
public SpriteHandle XboxOne;
|
||||
public SpriteHandle WindowsStore;
|
||||
public SpriteHandle Linux;
|
||||
public SpriteHandle PS4;
|
||||
public SpriteHandle XboxSeriesX;
|
||||
public SpriteHandle Android;
|
||||
|
||||
internal void GetIcons()
|
||||
internal void LoadIcons()
|
||||
{
|
||||
// Load asset
|
||||
// Load & validate
|
||||
var iconsAtlas = FlaxEngine.Content.LoadAsyncInternal<SpriteAtlas>(EditorAssets.IconsAtlas);
|
||||
if (iconsAtlas == null)
|
||||
{
|
||||
Editor.LogError("Cannot load editor icons atlas.");
|
||||
return;
|
||||
}
|
||||
if (iconsAtlas.WaitForLoaded())
|
||||
if (iconsAtlas is null || iconsAtlas.WaitForLoaded())
|
||||
{
|
||||
Editor.LogError("Failed to load editor icons atlas.");
|
||||
return;
|
||||
@@ -122,11 +144,11 @@ namespace FlaxEditor
|
||||
for (int i = 0; i < fields.Length; i++)
|
||||
{
|
||||
var field = fields[i];
|
||||
|
||||
var sprite = iconsAtlas.FindSprite(field.Name);
|
||||
if (!sprite.IsValid)
|
||||
{
|
||||
Editor.LogWarning(string.Format("Failed to load sprite icon \'{0}\'.", field.Name));
|
||||
}
|
||||
Editor.LogWarning($"Failed to load sprite icon \'{field.Name}\'.");
|
||||
|
||||
field.SetValue(this, sprite);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -349,6 +349,8 @@ namespace FlaxEditor.GUI
|
||||
/// </summary>
|
||||
protected virtual void OnSelectedIndexChanged()
|
||||
{
|
||||
if (_tooltips != null && _tooltips.Length == _items.Count)
|
||||
TooltipText = _selectedIndices.Count == 1 ? _tooltips[_selectedIndices[0]] : null;
|
||||
SelectedIndexChanged?.Invoke(this);
|
||||
}
|
||||
|
||||
|
||||
@@ -439,7 +439,7 @@ namespace FlaxEditor.GUI.ContextMenu
|
||||
}
|
||||
}
|
||||
}
|
||||
if (startIndex != -1)
|
||||
if (startIndex > 0 && startIndex <= _panel.Children.Count)
|
||||
{
|
||||
// No more items found so start from the top if there are matching items
|
||||
_panel.Children[startIndex - 1].Defocus();
|
||||
|
||||
@@ -61,7 +61,7 @@ namespace FlaxEditor.GUI.Dialogs
|
||||
public ColorSelector(float wheelSize = 64)
|
||||
: base(0, 0, wheelSize, wheelSize)
|
||||
{
|
||||
_colorWheelSprite = Editor.Instance.Icons.ColorWheel;
|
||||
_colorWheelSprite = Editor.Instance.Icons.ColorWheel128;
|
||||
_wheelRect = new Rectangle(0, 0, wheelSize, wheelSize);
|
||||
}
|
||||
|
||||
|
||||
@@ -348,7 +348,7 @@ namespace FlaxEditor.GUI.Docking
|
||||
// Cache data
|
||||
IsMouseRightButtonDown = true;
|
||||
if (MouseDownWindow != null)
|
||||
_panel.SelectTab(MouseDownWindow);
|
||||
_panel.SelectTab(MouseDownWindow, false);
|
||||
}
|
||||
else if (button == MouseButton.Middle)
|
||||
{
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace FlaxEditor.GUI
|
||||
/// <summary>
|
||||
/// The cached value from the UI.
|
||||
/// </summary>
|
||||
protected ulong _cachedValue;
|
||||
protected long _cachedValue;
|
||||
|
||||
/// <summary>
|
||||
/// True if has value cached, otherwise false.
|
||||
@@ -54,7 +54,7 @@ namespace FlaxEditor.GUI
|
||||
/// <summary>
|
||||
/// The value.
|
||||
/// </summary>
|
||||
public ulong Value;
|
||||
public long Value;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Entry"/> struct.
|
||||
@@ -62,7 +62,7 @@ namespace FlaxEditor.GUI
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="tooltip">The tooltip.</param>
|
||||
/// <param name="value">The value.</param>
|
||||
public Entry(string name, ulong value, string tooltip = null)
|
||||
public Entry(string name, long value, string tooltip = null)
|
||||
{
|
||||
Name = name;
|
||||
Tooltip = tooltip;
|
||||
@@ -88,13 +88,13 @@ namespace FlaxEditor.GUI
|
||||
public object EnumTypeValue
|
||||
{
|
||||
get => Enum.ToObject(_enumType, Value);
|
||||
set => Value = Convert.ToUInt64(value);
|
||||
set => Value = Convert.ToInt64(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the value.
|
||||
/// </summary>
|
||||
public ulong Value
|
||||
public long Value
|
||||
{
|
||||
get => _cachedValue;
|
||||
set
|
||||
@@ -209,7 +209,7 @@ namespace FlaxEditor.GUI
|
||||
/// </summary>
|
||||
protected void CacheValue()
|
||||
{
|
||||
ulong value = 0;
|
||||
long value = 0;
|
||||
if (IsFlags)
|
||||
{
|
||||
var selection = Selection;
|
||||
@@ -276,7 +276,7 @@ namespace FlaxEditor.GUI
|
||||
tooltip = tooltipAttr.Text;
|
||||
}
|
||||
|
||||
entries.Add(new Entry(name, Convert.ToUInt64(field.GetRawConstantValue()), tooltip));
|
||||
entries.Add(new Entry(name, Convert.ToInt64(field.GetRawConstantValue()), tooltip));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -295,9 +295,9 @@ namespace FlaxEditor.GUI
|
||||
}
|
||||
|
||||
// Calculate value that will be set after change
|
||||
ulong valueAfter = 0;
|
||||
long valueAfter = 0;
|
||||
bool isSelected = _selectedIndices.Contains(index);
|
||||
ulong selectedValue = entries[index].Value;
|
||||
long selectedValue = entries[index].Value;
|
||||
for (int i = 0; i < _selectedIndices.Count; i++)
|
||||
{
|
||||
int selectedIndex = _selectedIndices[i];
|
||||
|
||||
@@ -23,10 +23,7 @@ namespace FlaxEditor.GUI.Input
|
||||
value = Mathf.Clamp(value, _min, _max);
|
||||
if (Math.Abs(_value - value) > Mathf.Epsilon)
|
||||
{
|
||||
// Set value
|
||||
_value = value;
|
||||
|
||||
// Update
|
||||
UpdateText();
|
||||
OnValueChanged();
|
||||
}
|
||||
@@ -43,7 +40,6 @@ namespace FlaxEditor.GUI.Input
|
||||
{
|
||||
if (value > _max)
|
||||
throw new ArgumentException();
|
||||
|
||||
_min = value;
|
||||
Value = Value;
|
||||
}
|
||||
@@ -60,7 +56,6 @@ namespace FlaxEditor.GUI.Input
|
||||
{
|
||||
if (value < _min)
|
||||
throw new ArgumentException();
|
||||
|
||||
_max = value;
|
||||
Value = Value;
|
||||
}
|
||||
@@ -80,9 +75,19 @@ namespace FlaxEditor.GUI.Input
|
||||
public FloatValueBox(float value, float x = 0, float y = 0, float width = 120, float min = float.MinValue, float max = float.MaxValue, float slideSpeed = 1)
|
||||
: base(Mathf.Clamp(value, min, max), x, y, width, min, max, slideSpeed)
|
||||
{
|
||||
TryUseAutoSliderSpeed();
|
||||
UpdateText();
|
||||
}
|
||||
|
||||
private void TryUseAutoSliderSpeed()
|
||||
{
|
||||
var range = _max - _min;
|
||||
if (Mathf.IsOne(_slideSpeed) && range > Mathf.Epsilon * 200.0f && range < 1000000.0f)
|
||||
{
|
||||
_slideSpeed = range * 0.01f;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the value limits.
|
||||
/// </summary>
|
||||
@@ -103,6 +108,7 @@ namespace FlaxEditor.GUI.Input
|
||||
{
|
||||
_min = limits.Min;
|
||||
_max = Mathf.Max(_min, limits.Max);
|
||||
TryUseAutoSliderSpeed();
|
||||
Value = Value;
|
||||
}
|
||||
|
||||
@@ -115,6 +121,7 @@ namespace FlaxEditor.GUI.Input
|
||||
_min = limits.Min;
|
||||
_max = Mathf.Max(_min, limits.Max);
|
||||
_slideSpeed = limits.SliderSpeed;
|
||||
TryUseAutoSliderSpeed();
|
||||
Value = Value;
|
||||
}
|
||||
|
||||
|
||||
@@ -184,7 +184,7 @@ namespace FlaxEditor.GUI.Input
|
||||
var style = Style.Current;
|
||||
|
||||
// Draw sliding UI
|
||||
Render2D.DrawSprite(style.Scale, SlideRect, style.Foreground);
|
||||
Render2D.DrawSprite(style.Scalar, SlideRect, style.Foreground);
|
||||
|
||||
// Check if is sliding
|
||||
if (_isSliding)
|
||||
|
||||
@@ -82,14 +82,15 @@ namespace FlaxEditor.GUI
|
||||
var icons = Editor.Instance.Icons;
|
||||
var platforms = new[]
|
||||
{
|
||||
new PlatformData(PlatformType.Windows, icons.Windows, "Windows"),
|
||||
new PlatformData(PlatformType.XboxOne, icons.XboxOne, "Xbox One"),
|
||||
new PlatformData(PlatformType.UWP, icons.WindowsStore, "Windows Store"),
|
||||
new PlatformData(PlatformType.Linux, icons.Linux, "Linux"),
|
||||
new PlatformData(PlatformType.PS4, icons.PS4, "PlayStation 4"),
|
||||
new PlatformData(PlatformType.XboxScarlett, icons.XboxSeriesX, "Xbox Scarlett"),
|
||||
new PlatformData(PlatformType.Android, icons.Android, "Android"),
|
||||
new PlatformData(PlatformType.Switch, icons.ColorWheel, "Switch"),
|
||||
new PlatformData(PlatformType.Windows, icons.WindowsIcon128, "Windows"),
|
||||
new PlatformData(PlatformType.XboxOne, icons.XBoxOne128, "Xbox One"),
|
||||
new PlatformData(PlatformType.UWP, icons.UWPStore128, "Windows Store"),
|
||||
new PlatformData(PlatformType.Linux, icons.LinuxIcon128, "Linux"),
|
||||
new PlatformData(PlatformType.PS4, icons.PS4Icon128, "PlayStation 4"),
|
||||
new PlatformData(PlatformType.XboxScarlett, icons.XBoxScarletIcon128, "Xbox Scarlett"),
|
||||
new PlatformData(PlatformType.Android, icons.AndroidIcon128, "Android"),
|
||||
new PlatformData(PlatformType.Switch, icons.ColorWheel128, "Switch"),
|
||||
|
||||
};
|
||||
|
||||
const float IconSize = 48.0f;
|
||||
|
||||
@@ -79,7 +79,7 @@ namespace FlaxEditor.GUI
|
||||
var type = allTypes[i];
|
||||
if (_isValid(type))
|
||||
{
|
||||
var attributes = type.GetAttributes(false);
|
||||
var attributes = type.GetAttributes(true);
|
||||
if (attributes.FirstOrDefault(x => x is HideInEditorAttribute) == null)
|
||||
{
|
||||
AddItem(new TypeItemView(type, attributes));
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace FlaxEditor.GUI.Timeline.GUI
|
||||
var isMouseOver = IsMouseOver;
|
||||
var color = Gradient._data[Index].Value;
|
||||
var icons = Editor.Instance.Icons;
|
||||
var icon = icons.VisjectBoxClose;
|
||||
var icon = icons.VisjectBoxClosed32;
|
||||
|
||||
Render2D.DrawSprite(icon, new Rectangle(0.0f, 0.0f, 10.0f, 10.0f), isMouseOver ? Color.Gray : Color.Black);
|
||||
Render2D.DrawSprite(icon, new Rectangle(1.0f, 1.0f, 8.0f, 8.0f), color);
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace FlaxEditor.GUI.Timeline.GUI
|
||||
public override void Draw()
|
||||
{
|
||||
var style = Style.Current;
|
||||
var icon = Editor.Instance.Icons.VisjectArrowClose;
|
||||
var icon = Editor.Instance.Icons.VisjectArrowClosed32;
|
||||
var timeAxisHeaderOffset = -_timeline.MediaBackground.ViewOffset.Y;
|
||||
|
||||
Matrix3x3.RotationZ(Mathf.PiOverTwo, out var m1);
|
||||
|
||||
@@ -738,7 +738,7 @@ namespace FlaxEditor.GUI.Timeline
|
||||
_playbackNavigation[0] = new Image(playbackButtonsPanel.Width, 0, playbackButtonsSize, playbackButtonsSize)
|
||||
{
|
||||
TooltipText = "Rewind to timeline start (Home)",
|
||||
Brush = new SpriteBrush(icons.Step32),
|
||||
Brush = new SpriteBrush(icons.Skip64),
|
||||
Enabled = false,
|
||||
Visible = false,
|
||||
Rotation = 180.0f,
|
||||
@@ -750,7 +750,7 @@ namespace FlaxEditor.GUI.Timeline
|
||||
_playbackNavigation[1] = new Image(playbackButtonsPanel.Width, 0, playbackButtonsSize, playbackButtonsSize)
|
||||
{
|
||||
TooltipText = "Seek back to the previous keyframe (Page Down)",
|
||||
Brush = new SpriteBrush(icons.Next32),
|
||||
Brush = new SpriteBrush(icons.Shift64),
|
||||
Enabled = false,
|
||||
Visible = false,
|
||||
Rotation = 180.0f,
|
||||
@@ -766,7 +766,7 @@ namespace FlaxEditor.GUI.Timeline
|
||||
_playbackNavigation[2] = new Image(playbackButtonsPanel.Width, 0, playbackButtonsSize, playbackButtonsSize)
|
||||
{
|
||||
TooltipText = "Move one frame back (Left Arrow)",
|
||||
Brush = new SpriteBrush(icons.ArrowLeft32),
|
||||
Brush = new SpriteBrush(icons.Left32),
|
||||
Enabled = false,
|
||||
Visible = false,
|
||||
Parent = playbackButtonsPanel
|
||||
@@ -779,7 +779,7 @@ namespace FlaxEditor.GUI.Timeline
|
||||
_playbackStop = new Image(playbackButtonsPanel.Width, 0, playbackButtonsSize, playbackButtonsSize)
|
||||
{
|
||||
TooltipText = "Stop playback",
|
||||
Brush = new SpriteBrush(icons.Stop32),
|
||||
Brush = new SpriteBrush(icons.Stop64),
|
||||
Visible = false,
|
||||
Enabled = false,
|
||||
Parent = playbackButtonsPanel
|
||||
@@ -792,7 +792,7 @@ namespace FlaxEditor.GUI.Timeline
|
||||
_playbackPlay = new Image(playbackButtonsPanel.Width, 0, playbackButtonsSize, playbackButtonsSize)
|
||||
{
|
||||
TooltipText = "Play/pause playback (Space)",
|
||||
Brush = new SpriteBrush(icons.Play32),
|
||||
Brush = new SpriteBrush(icons.Play64),
|
||||
Visible = false,
|
||||
Tag = false, // Set to true if image is set to Pause, false if Play
|
||||
Parent = playbackButtonsPanel
|
||||
@@ -805,7 +805,7 @@ namespace FlaxEditor.GUI.Timeline
|
||||
_playbackNavigation[3] = new Image(playbackButtonsPanel.Width, 0, playbackButtonsSize, playbackButtonsSize)
|
||||
{
|
||||
TooltipText = "Move one frame forward (Right Arrow)",
|
||||
Brush = new SpriteBrush(icons.ArrowRight32),
|
||||
Brush = new SpriteBrush(icons.Right32),
|
||||
Enabled = false,
|
||||
Visible = false,
|
||||
Parent = playbackButtonsPanel
|
||||
@@ -816,7 +816,7 @@ namespace FlaxEditor.GUI.Timeline
|
||||
_playbackNavigation[4] = new Image(playbackButtonsPanel.Width, 0, playbackButtonsSize, playbackButtonsSize)
|
||||
{
|
||||
TooltipText = "Seek to the next keyframe (Page Up)",
|
||||
Brush = new SpriteBrush(icons.Next32),
|
||||
Brush = new SpriteBrush(icons.Shift64),
|
||||
Enabled = false,
|
||||
Visible = false,
|
||||
Parent = playbackButtonsPanel
|
||||
@@ -831,7 +831,7 @@ namespace FlaxEditor.GUI.Timeline
|
||||
_playbackNavigation[5] = new Image(playbackButtonsPanel.Width, 0, playbackButtonsSize, playbackButtonsSize)
|
||||
{
|
||||
TooltipText = "Rewind to timeline end (End)",
|
||||
Brush = new SpriteBrush(icons.Step32),
|
||||
Brush = new SpriteBrush(icons.Skip64),
|
||||
Enabled = false,
|
||||
Visible = false,
|
||||
Parent = playbackButtonsPanel
|
||||
@@ -1189,7 +1189,7 @@ namespace FlaxEditor.GUI.Timeline
|
||||
{
|
||||
_playbackPlay.Visible = true;
|
||||
_playbackPlay.Enabled = _canPlayPauseStop;
|
||||
_playbackPlay.Brush = new SpriteBrush(icons.Play32);
|
||||
_playbackPlay.Brush = new SpriteBrush(icons.Play64);
|
||||
_playbackPlay.Tag = false;
|
||||
}
|
||||
if (_positionHandle != null)
|
||||
@@ -1215,7 +1215,7 @@ namespace FlaxEditor.GUI.Timeline
|
||||
{
|
||||
_playbackPlay.Visible = true;
|
||||
_playbackPlay.Enabled = _canPlayPauseStop;
|
||||
_playbackPlay.Brush = new SpriteBrush(icons.Pause32);
|
||||
_playbackPlay.Brush = new SpriteBrush(icons.Pause64);
|
||||
_playbackPlay.Tag = true;
|
||||
}
|
||||
if (_positionHandle != null)
|
||||
@@ -1241,7 +1241,7 @@ namespace FlaxEditor.GUI.Timeline
|
||||
{
|
||||
_playbackPlay.Visible = true;
|
||||
_playbackPlay.Enabled = _canPlayPauseStop;
|
||||
_playbackPlay.Brush = new SpriteBrush(icons.Play32);
|
||||
_playbackPlay.Brush = new SpriteBrush(icons.Play64);
|
||||
_playbackPlay.Tag = false;
|
||||
}
|
||||
if (_positionHandle != null)
|
||||
|
||||
@@ -322,7 +322,7 @@ namespace FlaxEditor.GUI.Timeline.Tracks
|
||||
IsScrollable = false,
|
||||
Color = Style.Current.ForegroundGrey,
|
||||
Margin = new Margin(1),
|
||||
Brush = new SpriteBrush(icons.ArrowRight32),
|
||||
Brush = new SpriteBrush(icons.Right32),
|
||||
Offsets = new Margin(-buttonSize - 2 + _muteCheckbox.Offsets.Left, buttonSize, buttonSize * -0.5f, buttonSize),
|
||||
Parent = this,
|
||||
};
|
||||
@@ -335,7 +335,7 @@ namespace FlaxEditor.GUI.Timeline.Tracks
|
||||
IsScrollable = false,
|
||||
Color = Style.Current.ForegroundGrey,
|
||||
Margin = new Margin(3),
|
||||
Brush = new SpriteBrush(icons.Add48),
|
||||
Brush = new SpriteBrush(icons.Add32),
|
||||
Offsets = new Margin(-buttonSize - 2 + rightKey.Offsets.Left, buttonSize, buttonSize * -0.5f, buttonSize),
|
||||
Parent = this,
|
||||
};
|
||||
@@ -348,7 +348,7 @@ namespace FlaxEditor.GUI.Timeline.Tracks
|
||||
IsScrollable = false,
|
||||
Color = Style.Current.ForegroundGrey,
|
||||
Margin = new Margin(1),
|
||||
Brush = new SpriteBrush(icons.ArrowLeft32),
|
||||
Brush = new SpriteBrush(icons.Left32),
|
||||
Offsets = new Margin(-buttonSize - 2 + addKey.Offsets.Left, buttonSize, buttonSize * -0.5f, buttonSize),
|
||||
Parent = this,
|
||||
};
|
||||
|
||||
@@ -695,7 +695,7 @@ namespace FlaxEditor.GUI.Timeline.Tracks
|
||||
IsScrollable = false,
|
||||
Color = Style.Current.ForegroundGrey,
|
||||
Margin = new Margin(1),
|
||||
Brush = new SpriteBrush(icons.Camera32),
|
||||
Brush = new SpriteBrush(icons.Camera64),
|
||||
Offsets = new Margin(-buttonSize - 2 + _selectActor.Offsets.Left, buttonSize, buttonSize * -0.5f, buttonSize),
|
||||
Parent = this,
|
||||
};
|
||||
|
||||
@@ -128,7 +128,7 @@ namespace FlaxEditor.GUI.Timeline.Tracks
|
||||
IsScrollable = false,
|
||||
Color = Style.Current.ForegroundGrey,
|
||||
Margin = new Margin(1),
|
||||
Brush = new SpriteBrush(icons.ArrowRight32),
|
||||
Brush = new SpriteBrush(icons.Right64),
|
||||
Offsets = new Margin(-buttonSize - 2 + uiLeft, buttonSize, buttonSize * -0.5f, buttonSize),
|
||||
Parent = this,
|
||||
};
|
||||
@@ -138,9 +138,9 @@ namespace FlaxEditor.GUI.Timeline.Tracks
|
||||
AutoFocus = true,
|
||||
AnchorPreset = AnchorPresets.MiddleRight,
|
||||
IsScrollable = false,
|
||||
Color = Style.Current.ForegroundGrey,
|
||||
Color = Style.Current.Foreground,
|
||||
Margin = new Margin(3),
|
||||
Brush = new SpriteBrush(icons.Add48),
|
||||
Brush = new SpriteBrush(icons.Add64),
|
||||
Offsets = new Margin(-buttonSize - 2 + _rightKey.Offsets.Left, buttonSize, buttonSize * -0.5f, buttonSize),
|
||||
Parent = this,
|
||||
};
|
||||
@@ -150,9 +150,9 @@ namespace FlaxEditor.GUI.Timeline.Tracks
|
||||
AutoFocus = true,
|
||||
AnchorPreset = AnchorPresets.MiddleRight,
|
||||
IsScrollable = false,
|
||||
Color = Style.Current.ForegroundGrey,
|
||||
Color = Style.Current.Foreground,
|
||||
Margin = new Margin(1),
|
||||
Brush = new SpriteBrush(icons.ArrowLeft32),
|
||||
Brush = new SpriteBrush(icons.Left64),
|
||||
Offsets = new Margin(-buttonSize - 2 + _addKey.Offsets.Left, buttonSize, buttonSize * -0.5f, buttonSize),
|
||||
Parent = this,
|
||||
};
|
||||
|
||||
@@ -4,6 +4,8 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using FlaxEditor.Utilities;
|
||||
using FlaxEngine;
|
||||
using Newtonsoft.Json;
|
||||
using JsonSerializer = FlaxEngine.Json.JsonSerializer;
|
||||
|
||||
namespace FlaxEditor.History
|
||||
{
|
||||
@@ -114,6 +116,8 @@ namespace FlaxEditor.History
|
||||
public object TargetInstance;
|
||||
}
|
||||
|
||||
internal static JsonSerializerSettings JsonSettings;
|
||||
|
||||
// For objects that cannot be referenced in undo action like: FlaxEngine.Object or SceneGraphNode we store them in DataStorage,
|
||||
// otherwise here:
|
||||
private readonly object TargetInstance;
|
||||
@@ -177,6 +181,24 @@ namespace FlaxEditor.History
|
||||
};
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override DataStorage Data
|
||||
{
|
||||
protected set
|
||||
{
|
||||
// Inject objects typename serialization to prevent data type mismatch when loading from saved state
|
||||
var settings = JsonSettings;
|
||||
if (settings == null)
|
||||
{
|
||||
settings = JsonSerializer.CreateDefaultSettings(false);
|
||||
settings.TypeNameHandling = TypeNameHandling.All;
|
||||
JsonSettings = settings;
|
||||
}
|
||||
_data = JsonConvert.SerializeObject(value, Formatting.Indented, settings);
|
||||
//Editor.Log(_data);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ActionString { get; }
|
||||
|
||||
|
||||
@@ -96,10 +96,9 @@ struct InternalTextureOptions
|
||||
to->Sprites.EnsureCapacity(count);
|
||||
for (int32 i = 0; i < count; i++)
|
||||
{
|
||||
Sprite sprite;
|
||||
Sprite& sprite = to->Sprites.AddOne();
|
||||
sprite.Area = mono_array_get(from->SpriteAreas, Rectangle, i);
|
||||
sprite.Name = MUtils::ToString(mono_array_get(from->SpriteNames, MonoString*, i));
|
||||
to->Sprites.Add(sprite);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -125,7 +124,7 @@ struct InternalTextureOptions
|
||||
{
|
||||
const auto domain = mono_domain_get();
|
||||
int32 count = from->Sprites.Count();
|
||||
auto rectClass = Scripting::FindClass("FlaxEngine.Rectangle");
|
||||
auto rectClass = Rectangle::TypeInitializer.GetType().ManagedClass;
|
||||
ASSERT(rectClass != nullptr);
|
||||
to->SpriteAreas = mono_array_new(domain, rectClass->GetNative(), count);
|
||||
to->SpriteNames = mono_array_new(domain, mono_get_string_class(), count);
|
||||
@@ -521,13 +520,14 @@ public:
|
||||
return AssetsImportingManager::Create(AssetsImportingManager::CreateVisualScriptTag, outputPath, &baseTypename);
|
||||
}
|
||||
|
||||
static bool CanImport(MonoString* extensionObj)
|
||||
static MonoString* CanImport(MonoString* extensionObj)
|
||||
{
|
||||
String extension;
|
||||
MUtils::ToString(extensionObj, extension);
|
||||
if (extension.Length() > 0 && extension[0] == '.')
|
||||
extension.Remove(0, 1);
|
||||
return AssetsImportingManager::GetImporter(extension) != nullptr;
|
||||
const AssetImporter* importer = AssetsImportingManager::GetImporter(extension);
|
||||
return importer ? MUtils::ToString(importer->ResultExtension) : nullptr;
|
||||
}
|
||||
|
||||
static bool Import(MonoString* inputPathObj, MonoString* outputPathObj, void* arg)
|
||||
|
||||
@@ -911,6 +911,8 @@ namespace FlaxEditor.Modules
|
||||
Proxy.Add(new ParticleSystemProxy());
|
||||
Proxy.Add(new SceneAnimationProxy());
|
||||
Proxy.Add(new CSharpScriptProxy());
|
||||
Proxy.Add(new CppAssetProxy());
|
||||
Proxy.Add(new CppStaticClassProxy());
|
||||
Proxy.Add(new CppScriptProxy());
|
||||
Proxy.Add(new SceneProxy());
|
||||
Proxy.Add(new PrefabProxy());
|
||||
@@ -923,32 +925,34 @@ namespace FlaxEditor.Modules
|
||||
Proxy.Add(new SkeletonMaskProxy());
|
||||
Proxy.Add(new GameplayGlobalsProxy());
|
||||
Proxy.Add(new VisualScriptProxy());
|
||||
Proxy.Add(new LocalizedStringTableProxy());
|
||||
Proxy.Add(new FileProxy());
|
||||
Proxy.Add(new SpawnableJsonAssetProxy<PhysicalMaterial>());
|
||||
|
||||
// Settings
|
||||
Proxy.Add(new SettingsProxy(typeof(GameSettings)));
|
||||
Proxy.Add(new SettingsProxy(typeof(TimeSettings)));
|
||||
Proxy.Add(new SettingsProxy(typeof(LayersAndTagsSettings)));
|
||||
Proxy.Add(new SettingsProxy(typeof(PhysicsSettings)));
|
||||
Proxy.Add(new SettingsProxy(typeof(GraphicsSettings)));
|
||||
Proxy.Add(new SettingsProxy(typeof(NavigationSettings)));
|
||||
Proxy.Add(new SettingsProxy(typeof(BuildSettings)));
|
||||
Proxy.Add(new SettingsProxy(typeof(InputSettings)));
|
||||
Proxy.Add(new SettingsProxy(typeof(WindowsPlatformSettings)));
|
||||
Proxy.Add(new SettingsProxy(typeof(UWPPlatformSettings)));
|
||||
Proxy.Add(new SettingsProxy(typeof(LinuxPlatformSettings)));
|
||||
Proxy.Add(new SettingsProxy(typeof(GameSettings), Editor.Instance.Icons.GameSettings128));
|
||||
Proxy.Add(new SettingsProxy(typeof(TimeSettings), Editor.Instance.Icons.TimeSettings128));
|
||||
Proxy.Add(new SettingsProxy(typeof(LayersAndTagsSettings), Editor.Instance.Icons.LayersTagsSettings128));
|
||||
Proxy.Add(new SettingsProxy(typeof(PhysicsSettings), Editor.Instance.Icons.PhysicsSettings128));
|
||||
Proxy.Add(new SettingsProxy(typeof(GraphicsSettings), Editor.Instance.Icons.GraphicsSettings128));
|
||||
Proxy.Add(new SettingsProxy(typeof(NavigationSettings), Editor.Instance.Icons.NavigationSettings128));
|
||||
Proxy.Add(new SettingsProxy(typeof(LocalizationSettings), Editor.Instance.Icons.Document128));
|
||||
Proxy.Add(new SettingsProxy(typeof(BuildSettings), Editor.Instance.Icons.BuildSettings128));
|
||||
Proxy.Add(new SettingsProxy(typeof(InputSettings), Editor.Instance.Icons.InputSettings128));
|
||||
Proxy.Add(new SettingsProxy(typeof(WindowsPlatformSettings), Editor.Instance.Icons.WindowsSettings128));
|
||||
Proxy.Add(new SettingsProxy(typeof(UWPPlatformSettings), Editor.Instance.Icons.UWPSettings128));
|
||||
Proxy.Add(new SettingsProxy(typeof(LinuxPlatformSettings), Editor.Instance.Icons.LinuxSettings128));
|
||||
var typePS4PlatformSettings = TypeUtils.GetManagedType(GameSettings.PS4PlatformSettingsTypename);
|
||||
if (typePS4PlatformSettings != null)
|
||||
Proxy.Add(new SettingsProxy(typePS4PlatformSettings));
|
||||
Proxy.Add(new SettingsProxy(typePS4PlatformSettings, Editor.Instance.Icons.PlaystationSettings128));
|
||||
var typeXboxScarlettPlatformSettings = TypeUtils.GetManagedType(GameSettings.XboxScarlettPlatformSettingsTypename);
|
||||
if (typeXboxScarlettPlatformSettings != null)
|
||||
Proxy.Add(new SettingsProxy(typeXboxScarlettPlatformSettings));
|
||||
Proxy.Add(new SettingsProxy(typeof(AndroidPlatformSettings)));
|
||||
Proxy.Add(new SettingsProxy(typeXboxScarlettPlatformSettings, Editor.Instance.Icons.XBoxScarletIcon128));
|
||||
Proxy.Add(new SettingsProxy(typeof(AndroidPlatformSettings), Editor.Instance.Icons.AndroidSettings128));
|
||||
var typeSwitchPlatformSettings = TypeUtils.GetManagedType(GameSettings.SwitchPlatformSettingsTypename);
|
||||
if (typeSwitchPlatformSettings != null)
|
||||
Proxy.Add(new SettingsProxy(typeSwitchPlatformSettings));
|
||||
Proxy.Add(new SettingsProxy(typeof(AudioSettings)));
|
||||
Proxy.Add(new SettingsProxy(typeSwitchPlatformSettings, Editor.Instance.Icons.Document128));
|
||||
Proxy.Add(new SettingsProxy(typeof(AudioSettings), Editor.Instance.Icons.AudioSettings128));
|
||||
|
||||
// Last add generic json (won't override other json proxies)
|
||||
Proxy.Add(new GenericJsonAssetProxy());
|
||||
|
||||
@@ -118,6 +118,25 @@ namespace FlaxEditor.Modules
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check proxy name restrictions
|
||||
if (item is NewItem ni)
|
||||
{
|
||||
if (!ni.Proxy.IsFileNameValid(shortName))
|
||||
{
|
||||
hint = "Name does not follow " + ni.Proxy.Name + " name restrictions !";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var proxy = Editor.ContentDatabase.GetProxy(item);
|
||||
if (proxy != null && !proxy.IsFileNameValid(shortName))
|
||||
{
|
||||
hint = "Name does not follow " + proxy.Name + " name restrictions !";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Cache data
|
||||
string sourcePath = item.Path;
|
||||
string sourceFolder = System.IO.Path.GetDirectoryName(sourcePath);
|
||||
|
||||
@@ -309,6 +309,7 @@ namespace FlaxEditor.Modules
|
||||
{ "FlaxEditor.Content.Settings.InputSettings", "Settings" },
|
||||
{ "FlaxEditor.Content.Settings.LayersAndTagsSettings", "Settings" },
|
||||
{ "FlaxEditor.Content.Settings.NavigationSettings", "Settings" },
|
||||
{ "FlaxEditor.Content.Settings.LocalizationSettings", "Settings" },
|
||||
{ "FlaxEditor.Content.Settings.PhysicsSettings", "Settings" },
|
||||
{ "FlaxEditor.Content.Settings.TimeSettings", "Settings" },
|
||||
{ "FlaxEditor.Content.Settings.UWPPlatformSettings", "Settings" },
|
||||
|
||||
@@ -193,12 +193,10 @@ namespace FlaxEditor.Modules
|
||||
var extension = System.IO.Path.GetExtension(inputPath) ?? string.Empty;
|
||||
|
||||
// Check if given file extension is a binary asset (.flax files) and can be imported by the engine
|
||||
bool isBinaryAsset = Editor.CanImport(extension);
|
||||
string outputExtension;
|
||||
if (isBinaryAsset)
|
||||
bool isBuilt = Editor.CanImport(extension, out var outputExtension);
|
||||
if (isBuilt)
|
||||
{
|
||||
// Flax it up!
|
||||
outputExtension = ".flax";
|
||||
outputExtension = '.' + outputExtension;
|
||||
|
||||
if (!targetLocation.CanHaveAssets)
|
||||
{
|
||||
@@ -234,7 +232,7 @@ namespace FlaxEditor.Modules
|
||||
var shortName = System.IO.Path.GetFileNameWithoutExtension(inputPath);
|
||||
var outputPath = System.IO.Path.Combine(targetLocation.Path, shortName + outputExtension);
|
||||
|
||||
Import(inputPath, outputPath, isBinaryAsset, skipSettingsDialog, settings);
|
||||
Import(inputPath, outputPath, isBuilt, skipSettingsDialog, settings);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -243,10 +241,10 @@ namespace FlaxEditor.Modules
|
||||
/// </summary>
|
||||
/// <param name="inputPath">The input path.</param>
|
||||
/// <param name="outputPath">The output path.</param>
|
||||
/// <param name="isBinaryAsset">True if output file is a binary asset.</param>
|
||||
/// <param name="isInBuilt">True if use in-built importer (engine backend).</param>
|
||||
/// <param name="skipSettingsDialog">True if skip any popup dialogs showing for import options adjusting. Can be used when importing files from code.</param>
|
||||
/// <param name="settings">Import settings to override. Use null to skip this value.</param>
|
||||
private void Import(string inputPath, string outputPath, bool isBinaryAsset, bool skipSettingsDialog = false, object settings = null)
|
||||
private void Import(string inputPath, string outputPath, bool isInBuilt, bool skipSettingsDialog = false, object settings = null)
|
||||
{
|
||||
lock (_requests)
|
||||
{
|
||||
@@ -254,7 +252,7 @@ namespace FlaxEditor.Modules
|
||||
{
|
||||
InputPath = inputPath,
|
||||
OutputPath = outputPath,
|
||||
IsBinaryAsset = isBinaryAsset,
|
||||
IsInBuilt = isInBuilt,
|
||||
SkipSettingsDialog = skipSettingsDialog,
|
||||
Settings = settings,
|
||||
});
|
||||
|
||||
@@ -190,7 +190,7 @@ namespace FlaxEditor.Modules
|
||||
if (isDuringBreakpointHang)
|
||||
{
|
||||
play.Checked = false;
|
||||
play.Icon = Editor.Icons.Stop32;
|
||||
play.Icon = Editor.Icons.Stop64;
|
||||
pause.Enabled = false;
|
||||
pause.Checked = true;
|
||||
pause.AutoCheck = false;
|
||||
@@ -199,7 +199,7 @@ namespace FlaxEditor.Modules
|
||||
else if (isPlayMode)
|
||||
{
|
||||
play.Checked = false;
|
||||
play.Icon = Editor.Icons.Stop32;
|
||||
play.Icon = Editor.Icons.Stop64;
|
||||
pause.Enabled = true;
|
||||
pause.Checked = Editor.StateMachine.PlayingState.IsPaused;
|
||||
pause.AutoCheck = false;
|
||||
@@ -208,7 +208,7 @@ namespace FlaxEditor.Modules
|
||||
else
|
||||
{
|
||||
play.Checked = Editor.Simulation.IsPlayModeRequested;
|
||||
play.Icon = Editor.Icons.Play32;
|
||||
play.Icon = Editor.Icons.Play64;
|
||||
pause.Enabled = canEnterPlayMode;
|
||||
pause.AutoCheck = true;
|
||||
step.Enabled = false;
|
||||
@@ -501,20 +501,20 @@ namespace FlaxEditor.Modules
|
||||
Parent = mainWindow,
|
||||
};
|
||||
|
||||
_toolStripSaveAll = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.Save32, Editor.SaveAll).LinkTooltip("Save all (Ctrl+S)");
|
||||
_toolStripSaveAll = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.Save64, Editor.SaveAll).LinkTooltip("Save all (Ctrl+S)");
|
||||
ToolStrip.AddSeparator();
|
||||
_toolStripUndo = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.Undo32, Editor.PerformUndo).LinkTooltip("Undo (Ctrl+Z)");
|
||||
_toolStripRedo = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.Redo32, Editor.PerformRedo).LinkTooltip("Redo (Ctrl+Y)");
|
||||
_toolStripUndo = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.Undo64, Editor.PerformUndo).LinkTooltip("Undo (Ctrl+Z)");
|
||||
_toolStripRedo = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.Redo64, Editor.PerformRedo).LinkTooltip("Redo (Ctrl+Y)");
|
||||
ToolStrip.AddSeparator();
|
||||
_toolStripTranslate = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.Translate32, () => Editor.MainTransformGizmo.ActiveMode = TransformGizmoBase.Mode.Translate).LinkTooltip("Change Gizmo tool mode to Translate (1)");
|
||||
_toolStripRotate = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.Rotate32, () => Editor.MainTransformGizmo.ActiveMode = TransformGizmoBase.Mode.Rotate).LinkTooltip("Change Gizmo tool mode to Rotate (2)");
|
||||
_toolStripScale = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.Scale32, () => Editor.MainTransformGizmo.ActiveMode = TransformGizmoBase.Mode.Scale).LinkTooltip("Change Gizmo tool mode to Scale (3)");
|
||||
ToolStrip.AddSeparator();
|
||||
_toolStripBuildScenes = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.Build32, Editor.BuildScenesOrCancel).LinkTooltip("Build scenes data - CSG, navmesh, static lighting, env probes - configurable via Build Actions in editor options (Ctrl+F10)");
|
||||
_toolStripBuildScenes = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.Build64, Editor.BuildScenesOrCancel).LinkTooltip("Build scenes data - CSG, navmesh, static lighting, env probes - configurable via Build Actions in editor options (Ctrl+F10)");
|
||||
ToolStrip.AddSeparator();
|
||||
_toolStripPlay = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.Play32, Editor.Simulation.RequestPlayOrStopPlay).LinkTooltip("Start/Stop game (F5)");
|
||||
_toolStripPause = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.Pause32, Editor.Simulation.RequestResumeOrPause).LinkTooltip("Pause/Resume game(F6)");
|
||||
_toolStripStep = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.Step32, Editor.Simulation.RequestPlayOneFrame).LinkTooltip("Step one frame in game");
|
||||
_toolStripPlay = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.Play64, Editor.Simulation.RequestPlayOrStopPlay).LinkTooltip("Start/Stop game (F5)");
|
||||
_toolStripPause = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.Pause64, Editor.Simulation.RequestResumeOrPause).LinkTooltip("Pause/Resume game(F6)");
|
||||
_toolStripStep = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.Skip64, Editor.Simulation.RequestPlayOneFrame).LinkTooltip("Step one frame in game");
|
||||
|
||||
UpdateToolstrip();
|
||||
}
|
||||
|
||||
@@ -248,10 +248,11 @@ namespace FlaxEditor.Options
|
||||
Cross = Editor.Icons.Cross12,
|
||||
CheckBoxIntermediate = Editor.Icons.CheckBoxIntermediate12,
|
||||
CheckBoxTick = Editor.Icons.CheckBoxTick12,
|
||||
StatusBarSizeGrip = Editor.Icons.StatusBarSizeGrip12,
|
||||
Translate = Editor.Icons.Translate16,
|
||||
Rotate = Editor.Icons.Rotate16,
|
||||
Scale = Editor.Icons.Scale16,
|
||||
StatusBarSizeGrip = Editor.Icons.WindowDrag12,
|
||||
Translate = Editor.Icons.Translate32,
|
||||
Rotate = Editor.Icons.Rotate32,
|
||||
Scale = Editor.Icons.Scale32,
|
||||
Scalar = Editor.Icons.Scalar32,
|
||||
|
||||
SharedTooltip = new Tooltip()
|
||||
};
|
||||
|
||||
@@ -194,7 +194,7 @@ namespace FlaxEditor.SceneGraph
|
||||
{
|
||||
get
|
||||
{
|
||||
var scene = _actor.Scene;
|
||||
var scene = _actor ? _actor.Scene : null;
|
||||
return scene != null ? SceneGraphFactory.FindNode(scene.ID) as SceneNode : null;
|
||||
}
|
||||
}
|
||||
@@ -235,7 +235,6 @@ namespace FlaxEditor.SceneGraph
|
||||
{
|
||||
if (!(value is ActorNode))
|
||||
throw new InvalidOperationException("ActorNode can have only ActorNode as a parent node.");
|
||||
|
||||
base.ParentNode = value;
|
||||
}
|
||||
}
|
||||
@@ -289,6 +288,13 @@ namespace FlaxEditor.SceneGraph
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Action called after pasting actor in editor.
|
||||
/// </summary>
|
||||
public virtual void PostPaste()
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void OnParentChanged()
|
||||
{
|
||||
@@ -299,6 +305,7 @@ namespace FlaxEditor.SceneGraph
|
||||
// (eg. we build new node for spawned actor and link it to the game)
|
||||
if (_treeNode.Parent != null && !_treeNode.Parent.IsLayoutLocked)
|
||||
{
|
||||
_treeNode.IndexInParent = _actor.OrderInParent;
|
||||
_treeNode.Parent.SortChildren();
|
||||
|
||||
// Update UI
|
||||
|
||||
@@ -25,5 +25,20 @@ namespace FlaxEditor.SceneGraph.Actors
|
||||
if (Actor is UIControl uiControl)
|
||||
DebugDraw.DrawWireBox(uiControl.Bounds, Color.BlueViolet);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void PostPaste()
|
||||
{
|
||||
base.PostPaste();
|
||||
|
||||
var control = ((UIControl)Actor).Control;
|
||||
if (control != null)
|
||||
{
|
||||
if (control.Parent != null)
|
||||
control.Parent.PerformLayout();
|
||||
else
|
||||
control.PerformLayout();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,6 +86,10 @@ namespace FlaxEditor.SceneGraph.GUI
|
||||
}
|
||||
parent.SortChildren();
|
||||
}
|
||||
else if (Actor)
|
||||
{
|
||||
_orderInParent = Actor.OrderInParent;
|
||||
}
|
||||
}
|
||||
|
||||
internal void OnNameChanged()
|
||||
@@ -537,7 +541,7 @@ namespace FlaxEditor.SceneGraph.GUI
|
||||
var customAction = targetActor.HasPrefabLink ? new ReparentAction(targetActor) : null;
|
||||
using (new UndoBlock(ActorNode.Root.Undo, targetActor, "Change actor parent", customAction))
|
||||
{
|
||||
targetActor.SetParent(newParent, worldPositionLock);
|
||||
targetActor.SetParent(newParent, worldPositionLock, true);
|
||||
targetActor.OrderInParent = newOrder;
|
||||
}
|
||||
}
|
||||
@@ -550,7 +554,7 @@ namespace FlaxEditor.SceneGraph.GUI
|
||||
for (int i = 0; i < targetActors.Count; i++)
|
||||
{
|
||||
var targetActor = targetActors[i];
|
||||
targetActor.SetParent(newParent, worldPositionLock);
|
||||
targetActor.SetParent(newParent, worldPositionLock, true);
|
||||
targetActor.OrderInParent = newOrder;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,18 +112,9 @@ namespace FlaxEditor.SceneGraph
|
||||
{
|
||||
if (parentNode != value)
|
||||
{
|
||||
if (parentNode != null)
|
||||
{
|
||||
parentNode.ChildNodes.Remove(this);
|
||||
}
|
||||
|
||||
parentNode?.ChildNodes.Remove(this);
|
||||
parentNode = value;
|
||||
|
||||
if (parentNode != null)
|
||||
{
|
||||
parentNode.ChildNodes.Add(this);
|
||||
}
|
||||
|
||||
parentNode?.ChildNodes.Add(this);
|
||||
OnParentChanged();
|
||||
}
|
||||
}
|
||||
@@ -374,6 +365,7 @@ namespace FlaxEditor.SceneGraph
|
||||
/// <summary>
|
||||
/// Gets or sets the node state.
|
||||
/// </summary>
|
||||
[NoSerialize]
|
||||
public virtual StateData State
|
||||
{
|
||||
get => throw new NotImplementedException();
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "Engine/Core/Types/StringBuilder.h"
|
||||
#include "Engine/Debug/Exceptions/FileNotFoundException.h"
|
||||
#include "Engine/Engine/Engine.h"
|
||||
#include "Engine/Engine/Globals.h"
|
||||
#include "Engine/Platform/FileSystem.h"
|
||||
#include "Engine/Platform/FileSystemWatcher.h"
|
||||
#include "Engine/Threading/ThreadPool.h"
|
||||
|
||||
@@ -576,7 +576,7 @@ namespace FlaxEditor.Surface.Archetypes
|
||||
for (int i = 0; i < _parameters.Length; i++)
|
||||
{
|
||||
writer.Write(_parameters[i].Name); // Parameter name
|
||||
Utilities.Utils.WriteVariantType(writer, TypeUtils.GetType(_parameters[i].Type)); // Box type
|
||||
Utilities.VariantUtils.WriteVariantType(writer, TypeUtils.GetType(_parameters[i].Type)); // Box type
|
||||
}
|
||||
SetValue(2, stream.ToArray());
|
||||
}
|
||||
@@ -594,7 +594,7 @@ namespace FlaxEditor.Surface.Archetypes
|
||||
for (int i = 0; i < parametersCount; i++)
|
||||
{
|
||||
var parameterName = reader.ReadString(); // Parameter name
|
||||
var boxType = Utilities.Utils.ReadVariantType(reader); // Box type
|
||||
var boxType = Utilities.VariantUtils.ReadVariantType(reader); // Box type
|
||||
MakeBox(i + 1, parameterName, boxType);
|
||||
}
|
||||
}
|
||||
@@ -778,14 +778,14 @@ namespace FlaxEditor.Surface.Archetypes
|
||||
{
|
||||
reader.ReadByte(); // Version
|
||||
signature.IsStatic = reader.ReadBoolean(); // Is Static
|
||||
signature.ReturnType = Utilities.Utils.ReadVariantScriptType(reader); // Return type
|
||||
signature.ReturnType = Utilities.VariantUtils.ReadVariantScriptType(reader); // Return type
|
||||
var parametersCount = reader.ReadInt32(); // Parameters count
|
||||
signature.Params = parametersCount != 0 ? new SignatureParamInfo[parametersCount] : Utils.GetEmptyArray<SignatureParamInfo>();
|
||||
for (int i = 0; i < parametersCount; i++)
|
||||
{
|
||||
ref var param = ref signature.Params[i];
|
||||
param.Name = Utilities.Utils.ReadStr(reader, 11); // Parameter name
|
||||
param.Type = Utilities.Utils.ReadVariantScriptType(reader); // Parameter type
|
||||
param.Type = Utilities.VariantUtils.ReadVariantScriptType(reader); // Parameter type
|
||||
param.IsOut = reader.ReadByte() != 0; // Is parameter out
|
||||
}
|
||||
}
|
||||
@@ -799,14 +799,14 @@ namespace FlaxEditor.Surface.Archetypes
|
||||
{
|
||||
reader.ReadByte(); // Version
|
||||
signature.IsStatic = reader.ReadBoolean(); // Is Static
|
||||
signature.ReturnType = Utilities.Utils.ReadVariantScriptType(reader); // Return type
|
||||
signature.ReturnType = Utilities.VariantUtils.ReadVariantScriptType(reader); // Return type
|
||||
var parametersCount = reader.ReadInt32(); // Parameters count
|
||||
signature.Params = parametersCount != 0 ? new SignatureParamInfo[parametersCount] : Utils.GetEmptyArray<SignatureParamInfo>();
|
||||
for (int i = 0; i < parametersCount; i++)
|
||||
{
|
||||
ref var param = ref signature.Params[i];
|
||||
param.Name = reader.ReadString(); // Parameter name
|
||||
param.Type = Utilities.Utils.ReadVariantScriptType(reader); // Parameter type
|
||||
param.Type = Utilities.VariantUtils.ReadVariantScriptType(reader); // Parameter type
|
||||
param.IsOut = reader.ReadByte() != 0; // Is parameter out
|
||||
}
|
||||
}
|
||||
@@ -823,13 +823,13 @@ namespace FlaxEditor.Surface.Archetypes
|
||||
{
|
||||
writer.Write((byte)4); // Version
|
||||
writer.Write(methodInfo.IsStatic); // Is Static
|
||||
Utilities.Utils.WriteVariantType(writer, methodInfo.ValueType); // Return type
|
||||
Utilities.VariantUtils.WriteVariantType(writer, methodInfo.ValueType); // Return type
|
||||
writer.Write(parameters.Length); // Parameters count
|
||||
for (int i = 0; i < parameters.Length; i++)
|
||||
{
|
||||
ref var param = ref parameters[i];
|
||||
Utilities.Utils.WriteStr(writer, param.Name, 11); // Parameter name
|
||||
Utilities.Utils.WriteVariantType(writer, param.Type); // Parameter type
|
||||
Utilities.VariantUtils.WriteVariantType(writer, param.Type); // Parameter type
|
||||
writer.Write((byte)(param.IsOut ? 1 : 0)); // Is parameter out
|
||||
}
|
||||
return stream.ToArray();
|
||||
@@ -1434,14 +1434,14 @@ namespace FlaxEditor.Surface.Archetypes
|
||||
if (_signature.IsVirtual)
|
||||
flags |= Flags.Virtual;
|
||||
writer.Write((byte)flags); // Flags
|
||||
Utilities.Utils.WriteVariantType(writer, _signature.ReturnType); // Return Type
|
||||
Utilities.VariantUtils.WriteVariantType(writer, _signature.ReturnType); // Return Type
|
||||
var parametersCount = _signature.Parameters?.Length ?? 0;
|
||||
writer.Write(parametersCount); // Parameters count
|
||||
for (int i = 0; i < parametersCount; i++)
|
||||
{
|
||||
ref var param = ref _signature.Parameters[i];
|
||||
Utilities.Utils.WriteStrAnsi(writer, param.Name, 13); // Parameter name
|
||||
Utilities.Utils.WriteVariantType(writer, param.Type); // Parameter type
|
||||
Utilities.VariantUtils.WriteVariantType(writer, param.Type); // Parameter type
|
||||
writer.Write((byte)0); // Is parameter out
|
||||
writer.Write((byte)0); // Has default value
|
||||
}
|
||||
@@ -1470,13 +1470,13 @@ namespace FlaxEditor.Surface.Archetypes
|
||||
var flags = (Flags)reader.ReadByte(); // Flags
|
||||
_signature.IsStatic = (flags & Flags.Static) == Flags.Static;
|
||||
_signature.IsVirtual = (flags & Flags.Virtual) == Flags.Virtual;
|
||||
_signature.ReturnType = Utilities.Utils.ReadVariantScriptType(reader); // Return Type
|
||||
_signature.ReturnType = Utilities.VariantUtils.ReadVariantScriptType(reader); // Return Type
|
||||
var parametersCount = reader.ReadInt32(); // Parameters count
|
||||
_signature.Parameters = new Parameter[parametersCount];
|
||||
for (int i = 0; i < parametersCount; i++)
|
||||
{
|
||||
var paramName = Utilities.Utils.ReadStrAnsi(reader, 13); // Parameter name
|
||||
var paramType = Utilities.Utils.ReadVariantScriptType(reader); // Parameter type
|
||||
var paramType = Utilities.VariantUtils.ReadVariantScriptType(reader); // Parameter type
|
||||
var isOut = reader.ReadByte() != 0; // Is parameter out
|
||||
var hasDefaultValue = reader.ReadByte() != 0; // Has default value
|
||||
_signature.Parameters[i] = new Parameter
|
||||
@@ -1993,7 +1993,7 @@ namespace FlaxEditor.Surface.Archetypes
|
||||
}
|
||||
else if (_isBind)
|
||||
{
|
||||
_helperButton.Brush = new SpriteBrush(Editor.Instance.Icons.Add48);
|
||||
_helperButton.Brush = new SpriteBrush(Editor.Instance.Icons.Add64);
|
||||
_helperButton.Color = Color.Red;
|
||||
_helperButton.TooltipText = "Add new handler function and bind it to this event";
|
||||
_helperButton.Enabled = _signature != null;
|
||||
|
||||
@@ -171,7 +171,7 @@ namespace FlaxEditor.Surface.Archetypes
|
||||
for (int i = 0; i < fieldsLength; i++)
|
||||
{
|
||||
Utilities.Utils.WriteStr(writer, fields[i].Name, 11); // Field type
|
||||
Utilities.Utils.WriteVariantType(writer, fields[i].ValueType); // Field type
|
||||
Utilities.VariantUtils.WriteVariantType(writer, fields[i].ValueType); // Field type
|
||||
}
|
||||
Values[1] = stream.ToArray();
|
||||
}
|
||||
@@ -188,7 +188,7 @@ namespace FlaxEditor.Surface.Archetypes
|
||||
for (int i = 0; i < fieldsLength; i++)
|
||||
{
|
||||
var fieldName = Utilities.Utils.ReadStr(reader, 11); // Field name
|
||||
var fieldType = Utilities.Utils.ReadVariantType(reader); // Field type
|
||||
var fieldType = Utilities.VariantUtils.ReadVariantType(reader); // Field type
|
||||
MakeBox(i + 1, fieldName, new ScriptType(fieldType));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ namespace FlaxEditor.Surface.Archetypes
|
||||
color *= 1.3f;
|
||||
color.A = 1.0f;
|
||||
var icons = Editor.Instance.Icons;
|
||||
var icon = isSelected ? icons.VisjectArrowClose : icons.VisjectArrowOpen;
|
||||
var icon = isSelected ? icons.VisjectArrowClosed32 : icons.VisjectArrowOpen32;
|
||||
|
||||
Render2D.PushTransform(ref arrowTransform);
|
||||
Render2D.DrawSprite(icon, arrowRect, color);
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace FlaxEditor.Surface.Elements
|
||||
Width = archetype.Size.X;
|
||||
ParentNode = parentNode;
|
||||
Archetype = archetype;
|
||||
Value = (ulong)(int)ParentNode.Values[Archetype.ValueIndex];
|
||||
Value = (int)ParentNode.Values[Archetype.ValueIndex];
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -9,6 +9,8 @@ using FlaxEditor.GUI.Input;
|
||||
using FlaxEditor.Scripting;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
using Newtonsoft.Json;
|
||||
using JsonSerializer = FlaxEngine.Json.JsonSerializer;
|
||||
|
||||
namespace FlaxEditor.Surface.Elements
|
||||
{
|
||||
@@ -981,6 +983,121 @@ namespace FlaxEditor.Surface.Elements
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool OnMouseUp(Vector2 location, MouseButton button)
|
||||
{
|
||||
if (button == MouseButton.Right && Archetype.ValueIndex != -1)
|
||||
{
|
||||
var menu = new FlaxEditor.GUI.ContextMenu.ContextMenu();
|
||||
menu.AddButton("Copy value", OnCopyValue);
|
||||
var paste = menu.AddButton("Paste value", OnPasteValue);
|
||||
try
|
||||
{
|
||||
GetClipboardValue(out _, false);
|
||||
}
|
||||
catch
|
||||
{
|
||||
paste.Enabled = false;
|
||||
}
|
||||
|
||||
menu.Show(this, location);
|
||||
return true;
|
||||
}
|
||||
|
||||
return base.OnMouseUp(location, button);
|
||||
}
|
||||
|
||||
private bool GetClipboardValue(out object result, bool deserialize)
|
||||
{
|
||||
result = null;
|
||||
var text = Clipboard.Text;
|
||||
if (string.IsNullOrEmpty(text))
|
||||
return false;
|
||||
|
||||
object obj;
|
||||
var type = CurrentType;
|
||||
if (new ScriptType(typeof(FlaxEngine.Object)).IsAssignableFrom(type))
|
||||
{
|
||||
// Object reference
|
||||
if (text.Length != 32)
|
||||
return false;
|
||||
JsonSerializer.ParseID(text, out var id);
|
||||
obj = FlaxEngine.Object.Find<FlaxEngine.Object>(ref id);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Default
|
||||
obj = JsonConvert.DeserializeObject(text, TypeUtils.GetType(type), JsonSerializer.Settings);
|
||||
}
|
||||
|
||||
if (obj == null || type.IsInstanceOfType(obj))
|
||||
{
|
||||
result = obj;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void OnCopyValue()
|
||||
{
|
||||
var value = ParentNode.Values[Archetype.ValueIndex];
|
||||
|
||||
try
|
||||
{
|
||||
string text;
|
||||
if (value == null)
|
||||
{
|
||||
// Missing value
|
||||
var type = CurrentType;
|
||||
if (type.Type == typeof(bool))
|
||||
text = "false";
|
||||
else if (type.Type == typeof(byte) || type.Type == typeof(sbyte) || type.Type == typeof(char) || type.Type == typeof(short) || type.Type == typeof(ushort) || type.Type == typeof(int) || type.Type == typeof(uint) || type.Type == typeof(long) || type.Type == typeof(ulong))
|
||||
text = "0";
|
||||
else if (type.Type == typeof(float) || type.Type == typeof(double))
|
||||
text = "0.0";
|
||||
else if (type.Type == typeof(Vector2) || type.Type == typeof(Vector3) || type.Type == typeof(Vector4) || type.Type == typeof(Color))
|
||||
text = JsonSerializer.Serialize(TypeUtils.GetDefaultValue(type));
|
||||
else if (type.Type == typeof(string))
|
||||
text = "";
|
||||
else
|
||||
text = "null";
|
||||
}
|
||||
else if (value is FlaxEngine.Object asObject)
|
||||
{
|
||||
// Object reference
|
||||
text = JsonSerializer.GetStringID(asObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Default
|
||||
text = JsonSerializer.Serialize(value);
|
||||
}
|
||||
Clipboard.Text = text;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Editor.LogWarning(ex);
|
||||
Editor.LogError("Cannot copy property. See log for more info.");
|
||||
}
|
||||
}
|
||||
|
||||
private void OnPasteValue()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (GetClipboardValue(out var value, true))
|
||||
{
|
||||
ParentNode.SetValue(Archetype.ValueIndex, value);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Editor.LogWarning(ex);
|
||||
Editor.LogError("Cannot paste property value. See log for more info.");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the default value editor control.
|
||||
/// </summary>
|
||||
|
||||
@@ -224,10 +224,10 @@ namespace FlaxEditor.Surface
|
||||
},
|
||||
Icons =
|
||||
{
|
||||
BoxOpen = editor.Icons.VisjectBoxOpen,
|
||||
BoxClose = editor.Icons.VisjectBoxClose,
|
||||
ArrowOpen = editor.Icons.VisjectArrowOpen,
|
||||
ArrowClose = editor.Icons.VisjectArrowClose,
|
||||
BoxOpen = editor.Icons.VisjectBoxOpen32,
|
||||
BoxClose = editor.Icons.VisjectBoxClosed32,
|
||||
ArrowOpen = editor.Icons.VisjectArrowOpen32,
|
||||
ArrowClose = editor.Icons.VisjectArrowClosed32,
|
||||
},
|
||||
Background = editor.UI.VisjectSurfaceBackground,
|
||||
};
|
||||
|
||||
@@ -759,12 +759,12 @@ namespace FlaxEditor.Surface
|
||||
_propertiesEditor.Modified += OnPropertyEdited;
|
||||
|
||||
// Toolstrip
|
||||
_saveButton = (ToolStripButton)_toolstrip.AddButton(Editor.Icons.Save32, Save).LinkTooltip("Save");
|
||||
_saveButton = (ToolStripButton)_toolstrip.AddButton(Editor.Icons.Save64, Save).LinkTooltip("Save");
|
||||
_toolstrip.AddSeparator();
|
||||
_undoButton = (ToolStripButton)_toolstrip.AddButton(Editor.Icons.Undo32, _undo.PerformUndo).LinkTooltip("Undo (Ctrl+Z)");
|
||||
_redoButton = (ToolStripButton)_toolstrip.AddButton(Editor.Icons.Redo32, _undo.PerformRedo).LinkTooltip("Redo (Ctrl+Y)");
|
||||
_undoButton = (ToolStripButton)_toolstrip.AddButton(Editor.Icons.Undo64, _undo.PerformUndo).LinkTooltip("Undo (Ctrl+Z)");
|
||||
_redoButton = (ToolStripButton)_toolstrip.AddButton(Editor.Icons.Redo64, _undo.PerformRedo).LinkTooltip("Redo (Ctrl+Y)");
|
||||
_toolstrip.AddSeparator();
|
||||
_toolstrip.AddButton(editor.Icons.PageScale32, ShowWholeGraph).LinkTooltip("Show whole graph");
|
||||
_toolstrip.AddButton(editor.Icons.CenterView64, ShowWholeGraph).LinkTooltip("Show whole graph");
|
||||
|
||||
// Setup input actions
|
||||
InputActions.Add(options => options.Undo, _undo.PerformUndo);
|
||||
|
||||
@@ -140,22 +140,27 @@ namespace FlaxEditor.Actions
|
||||
|
||||
for (int i = 0; i < nodeParents.Count; i++)
|
||||
{
|
||||
// Fix name collisions (only for parents)
|
||||
var node = nodeParents[i];
|
||||
var parent = node.Actor?.Parent;
|
||||
if (parent != null)
|
||||
{
|
||||
// Fix name collisions
|
||||
string name = node.Name;
|
||||
Actor[] children = parent.Children;
|
||||
if (children.Any(x => x.Name == name))
|
||||
{
|
||||
// Generate new name
|
||||
node.Actor.Name = StringUtils.IncrementNameNumber(name, x => children.All(y => y.Name != x));
|
||||
}
|
||||
}
|
||||
|
||||
Editor.Instance.Scene.MarkSceneEdited(node.ParentScene);
|
||||
}
|
||||
|
||||
for (int i = 0; i < nodeParents.Count; i++)
|
||||
{
|
||||
var node = nodeParents[i];
|
||||
node.PostPaste();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -4,7 +4,6 @@ using System;
|
||||
using FlaxEditor.SceneGraph;
|
||||
using FlaxEngine;
|
||||
using Newtonsoft.Json;
|
||||
using JsonSerializer = FlaxEngine.Json.JsonSerializer;
|
||||
|
||||
namespace FlaxEditor
|
||||
{
|
||||
@@ -28,7 +27,6 @@ namespace FlaxEditor
|
||||
var id = Guid.Parse((string)reader.Value);
|
||||
return SceneGraphFactory.FindNode(id);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -56,19 +54,11 @@ namespace FlaxEditor
|
||||
/// <summary>
|
||||
/// Gets or sets the serialized undo data.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The data.
|
||||
/// </value>
|
||||
[NoSerialize]
|
||||
public TData Data
|
||||
public virtual TData Data
|
||||
{
|
||||
get => JsonConvert.DeserializeObject<TData>(_data, JsonSerializer.Settings);
|
||||
protected set => _data = JsonConvert.SerializeObject(value, Formatting.None, JsonSerializer.Settings);
|
||||
/*protected set
|
||||
{
|
||||
_data = JsonConvert.SerializeObject(value, Formatting.Indented, JsonSerializer.Settings);
|
||||
Debug.Info(_data);
|
||||
}*/
|
||||
get => JsonConvert.DeserializeObject<TData>(_data, FlaxEngine.Json.JsonSerializer.Settings);
|
||||
protected set => _data = JsonConvert.SerializeObject(value, Formatting.None, FlaxEngine.Json.JsonSerializer.Settings);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||
|
||||
#include "EditorUtilities.h"
|
||||
#include "Engine/Engine/Globals.h"
|
||||
#include "Engine/Platform/File.h"
|
||||
#include "Engine/Platform/FileSystem.h"
|
||||
#include "Engine/Core/Log.h"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
1072
Source/Editor/Utilities/VariantUtils.cs
Normal file
1072
Source/Editor/Utilities/VariantUtils.cs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -443,7 +443,7 @@ namespace FlaxEditor.Viewport
|
||||
// Camera speed widget
|
||||
var camSpeed = new ViewportWidgetsContainer(ViewportWidgetLocation.UpperRight);
|
||||
var camSpeedCM = new ContextMenu();
|
||||
var camSpeedButton = new ViewportWidgetButton(_movementSpeed.ToString(), Editor.Instance.Icons.ArrowRightBorder16, camSpeedCM)
|
||||
var camSpeedButton = new ViewportWidgetButton(_movementSpeed.ToString(), Editor.Instance.Icons.CamSpeed32, camSpeedCM)
|
||||
{
|
||||
Tag = this,
|
||||
TooltipText = "Camera speed scale"
|
||||
@@ -484,7 +484,7 @@ namespace FlaxEditor.Viewport
|
||||
// View Flags
|
||||
{
|
||||
var viewFlags = ViewWidgetButtonMenu.AddChildMenu("View Flags").ContextMenu;
|
||||
viewFlags.AddButton("Reset flags", () => Task.ViewFlags = ViewFlags.DefaultEditor).Icon = Editor.Instance.Icons.Rotate16;
|
||||
viewFlags.AddButton("Reset flags", () => Task.ViewFlags = ViewFlags.DefaultEditor).Icon = Editor.Instance.Icons.Rotate32;
|
||||
viewFlags.AddSeparator();
|
||||
for (int i = 0; i < EditorViewportViewFlagsValues.Length; i++)
|
||||
{
|
||||
@@ -974,7 +974,8 @@ namespace FlaxEditor.Viewport
|
||||
// Get input buttons and keys (skip if viewport has no focus or mouse is over a child control)
|
||||
bool useMouse = Mathf.IsInRange(_viewMousePos.X, 0, Width) && Mathf.IsInRange(_viewMousePos.Y, 0, Height);
|
||||
_prevInput = _input;
|
||||
if (ContainsFocus && GetChildAt(_viewMousePos, c => c.Visible) == null)
|
||||
var hit = GetChildAt(_viewMousePos, c => c.Visible && !(c is CanvasRootControl));
|
||||
if (ContainsFocus && hit == null)
|
||||
_input.Gather(win.Window, useMouse);
|
||||
else
|
||||
_input.Clear();
|
||||
|
||||
@@ -165,6 +165,11 @@ namespace FlaxEditor.Viewport
|
||||
/// </summary>
|
||||
public bool DrawDebugDraw = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the debug draw data for the viewport.
|
||||
/// </summary>
|
||||
public ViewportDebugDrawData DebugDrawData => _debugDrawData;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether show navigation mesh.
|
||||
/// </summary>
|
||||
@@ -219,7 +224,7 @@ namespace FlaxEditor.Viewport
|
||||
|
||||
// Transform space widget
|
||||
var transformSpaceWidget = new ViewportWidgetsContainer(ViewportWidgetLocation.UpperRight);
|
||||
var transformSpaceToggle = new ViewportWidgetButton(string.Empty, editor.Icons.World16, null, true)
|
||||
var transformSpaceToggle = new ViewportWidgetButton(string.Empty, editor.Icons.Globe32, null, true)
|
||||
{
|
||||
Checked = TransformGizmo.ActiveTransformSpace == TransformGizmoBase.TransformSpace.World,
|
||||
TooltipText = "Gizmo transform space (world or local)",
|
||||
@@ -230,7 +235,7 @@ namespace FlaxEditor.Viewport
|
||||
|
||||
// Scale snapping widget
|
||||
var scaleSnappingWidget = new ViewportWidgetsContainer(ViewportWidgetLocation.UpperRight);
|
||||
var enableScaleSnapping = new ViewportWidgetButton(string.Empty, editor.Icons.ScaleStep16, null, true)
|
||||
var enableScaleSnapping = new ViewportWidgetButton(string.Empty, editor.Icons.ScaleSnap32, null, true)
|
||||
{
|
||||
Checked = TransformGizmo.ScaleSnapEnabled,
|
||||
TooltipText = "Enable scale snapping",
|
||||
@@ -257,7 +262,7 @@ namespace FlaxEditor.Viewport
|
||||
|
||||
// Rotation snapping widget
|
||||
var rotateSnappingWidget = new ViewportWidgetsContainer(ViewportWidgetLocation.UpperRight);
|
||||
var enableRotateSnapping = new ViewportWidgetButton(string.Empty, editor.Icons.RotateStep16, null, true)
|
||||
var enableRotateSnapping = new ViewportWidgetButton(string.Empty, editor.Icons.RotateSnap32, null, true)
|
||||
{
|
||||
Checked = TransformGizmo.RotationSnapEnabled,
|
||||
TooltipText = "Enable rotation snapping",
|
||||
@@ -284,7 +289,7 @@ namespace FlaxEditor.Viewport
|
||||
|
||||
// Translation snapping widget
|
||||
var translateSnappingWidget = new ViewportWidgetsContainer(ViewportWidgetLocation.UpperRight);
|
||||
var enableTranslateSnapping = new ViewportWidgetButton(string.Empty, editor.Icons.Grid16, null, true)
|
||||
var enableTranslateSnapping = new ViewportWidgetButton(string.Empty, editor.Icons.Grid32, null, true)
|
||||
{
|
||||
Checked = TransformGizmo.TranslationSnapEnable,
|
||||
TooltipText = "Enable position snapping",
|
||||
@@ -311,7 +316,7 @@ namespace FlaxEditor.Viewport
|
||||
|
||||
// Gizmo mode widget
|
||||
var gizmoMode = new ViewportWidgetsContainer(ViewportWidgetLocation.UpperRight);
|
||||
_gizmoModeTranslate = new ViewportWidgetButton(string.Empty, editor.Icons.Translate16, null, true)
|
||||
_gizmoModeTranslate = new ViewportWidgetButton(string.Empty, editor.Icons.Translate32, null, true)
|
||||
{
|
||||
Tag = TransformGizmoBase.Mode.Translate,
|
||||
TooltipText = "Translate gizmo mode",
|
||||
@@ -319,14 +324,14 @@ namespace FlaxEditor.Viewport
|
||||
Parent = gizmoMode
|
||||
};
|
||||
_gizmoModeTranslate.Toggled += OnGizmoModeToggle;
|
||||
_gizmoModeRotate = new ViewportWidgetButton(string.Empty, editor.Icons.Rotate16, null, true)
|
||||
_gizmoModeRotate = new ViewportWidgetButton(string.Empty, editor.Icons.Rotate32, null, true)
|
||||
{
|
||||
Tag = TransformGizmoBase.Mode.Rotate,
|
||||
TooltipText = "Rotate gizmo mode",
|
||||
Parent = gizmoMode
|
||||
};
|
||||
_gizmoModeRotate.Toggled += OnGizmoModeToggle;
|
||||
_gizmoModeScale = new ViewportWidgetButton(string.Empty, editor.Icons.Scale16, null, true)
|
||||
_gizmoModeScale = new ViewportWidgetButton(string.Empty, editor.Icons.Scale32, null, true)
|
||||
{
|
||||
Tag = TransformGizmoBase.Mode.Scale,
|
||||
TooltipText = "Scale gizmo mode",
|
||||
@@ -389,10 +394,11 @@ namespace FlaxEditor.Viewport
|
||||
return;
|
||||
|
||||
// Create actor
|
||||
var parent = Level.GetScene(0);
|
||||
var actor = new Camera
|
||||
{
|
||||
StaticFlags = StaticFlags.None,
|
||||
Name = "Camera",
|
||||
Name = StringUtils.IncrementNameNumber("Camera", x => parent.GetChild(x) == null),
|
||||
Transform = ViewTransform,
|
||||
NearPlane = NearPlane,
|
||||
FarPlane = FarPlane,
|
||||
@@ -402,7 +408,7 @@ namespace FlaxEditor.Viewport
|
||||
};
|
||||
|
||||
// Spawn
|
||||
Editor.Instance.SceneEditing.Spawn(actor);
|
||||
Editor.Instance.SceneEditing.Spawn(actor, parent);
|
||||
}
|
||||
|
||||
private void OnBegin(RenderTask task, GPUContext context)
|
||||
@@ -877,6 +883,8 @@ namespace FlaxEditor.Viewport
|
||||
private void Spawn(Actor actor, ref Vector3 hitLocation)
|
||||
{
|
||||
actor.Position = PostProcessSpawnedActorLocation(actor, ref hitLocation);
|
||||
var parent = actor.Parent ?? Level.GetScene(0);
|
||||
actor.Name = StringUtils.IncrementNameNumber(actor.Name, x => parent.GetChild(x) == null);
|
||||
Editor.Instance.SceneEditing.Spawn(actor);
|
||||
Focus();
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ namespace FlaxEditor.Viewport
|
||||
|
||||
// Transform space widget
|
||||
var transformSpaceWidget = new ViewportWidgetsContainer(ViewportWidgetLocation.UpperRight);
|
||||
var transformSpaceToggle = new ViewportWidgetButton(string.Empty, window.Editor.Icons.World16, null, true)
|
||||
var transformSpaceToggle = new ViewportWidgetButton(string.Empty, window.Editor.Icons.Globe32, null, true)
|
||||
{
|
||||
Checked = TransformGizmo.ActiveTransformSpace == TransformGizmoBase.TransformSpace.World,
|
||||
TooltipText = "Gizmo transform space (world or local)",
|
||||
@@ -129,7 +129,7 @@ namespace FlaxEditor.Viewport
|
||||
|
||||
// Scale snapping widget
|
||||
var scaleSnappingWidget = new ViewportWidgetsContainer(ViewportWidgetLocation.UpperRight);
|
||||
var enableScaleSnapping = new ViewportWidgetButton(string.Empty, window.Editor.Icons.ScaleStep16, null, true)
|
||||
var enableScaleSnapping = new ViewportWidgetButton(string.Empty, window.Editor.Icons.ScaleSnap32, null, true)
|
||||
{
|
||||
Checked = TransformGizmo.ScaleSnapEnabled,
|
||||
TooltipText = "Enable scale snapping",
|
||||
@@ -156,7 +156,7 @@ namespace FlaxEditor.Viewport
|
||||
|
||||
// Rotation snapping widget
|
||||
var rotateSnappingWidget = new ViewportWidgetsContainer(ViewportWidgetLocation.UpperRight);
|
||||
var enableRotateSnapping = new ViewportWidgetButton(string.Empty, window.Editor.Icons.RotateStep16, null, true)
|
||||
var enableRotateSnapping = new ViewportWidgetButton(string.Empty, window.Editor.Icons.RotateSnap32, null, true)
|
||||
{
|
||||
Checked = TransformGizmo.RotationSnapEnabled,
|
||||
TooltipText = "Enable rotation snapping",
|
||||
@@ -183,7 +183,7 @@ namespace FlaxEditor.Viewport
|
||||
|
||||
// Translation snapping widget
|
||||
var translateSnappingWidget = new ViewportWidgetsContainer(ViewportWidgetLocation.UpperRight);
|
||||
var enableTranslateSnapping = new ViewportWidgetButton(string.Empty, window.Editor.Icons.Grid16, null, true)
|
||||
var enableTranslateSnapping = new ViewportWidgetButton(string.Empty, window.Editor.Icons.Grid32, null, true)
|
||||
{
|
||||
Checked = TransformGizmo.TranslationSnapEnable,
|
||||
TooltipText = "Enable position snapping",
|
||||
@@ -210,7 +210,7 @@ namespace FlaxEditor.Viewport
|
||||
|
||||
// Gizmo mode widget
|
||||
var gizmoMode = new ViewportWidgetsContainer(ViewportWidgetLocation.UpperRight);
|
||||
_gizmoModeTranslate = new ViewportWidgetButton(string.Empty, window.Editor.Icons.Translate16, null, true)
|
||||
_gizmoModeTranslate = new ViewportWidgetButton(string.Empty, window.Editor.Icons.Translate32, null, true)
|
||||
{
|
||||
Tag = TransformGizmoBase.Mode.Translate,
|
||||
TooltipText = "Translate gizmo mode",
|
||||
@@ -218,14 +218,14 @@ namespace FlaxEditor.Viewport
|
||||
Parent = gizmoMode
|
||||
};
|
||||
_gizmoModeTranslate.Toggled += OnGizmoModeToggle;
|
||||
_gizmoModeRotate = new ViewportWidgetButton(string.Empty, window.Editor.Icons.Rotate16, null, true)
|
||||
_gizmoModeRotate = new ViewportWidgetButton(string.Empty, window.Editor.Icons.Rotate32, null, true)
|
||||
{
|
||||
Tag = TransformGizmoBase.Mode.Rotate,
|
||||
TooltipText = "Rotate gizmo mode",
|
||||
Parent = gizmoMode
|
||||
};
|
||||
_gizmoModeRotate.Toggled += OnGizmoModeToggle;
|
||||
_gizmoModeScale = new ViewportWidgetButton(string.Empty, window.Editor.Icons.Scale16, null, true)
|
||||
_gizmoModeScale = new ViewportWidgetButton(string.Empty, window.Editor.Icons.Scale32, null, true)
|
||||
{
|
||||
Tag = TransformGizmoBase.Mode.Scale,
|
||||
TooltipText = "Scale gizmo mode",
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace FlaxEditor.Windows
|
||||
{
|
||||
Image icon = new Image(4, 4, 80, 80)
|
||||
{
|
||||
Brush = new SpriteBrush(Editor.Instance.Icons.Logo128),
|
||||
Brush = new SpriteBrush(Editor.Instance.Icons.FlaxLogo128),
|
||||
Parent = this
|
||||
};
|
||||
var nameLabel = new Label(icon.Right + 10, icon.Top, 200, 34)
|
||||
@@ -131,6 +131,7 @@ namespace FlaxEditor.Windows
|
||||
"LZ4 Library - Copyright (c) Yann Collet. All rights reserved.",
|
||||
"fmt - www.fmtlib.net",
|
||||
"minimp3 - www.github.com/lieff/minimp3",
|
||||
"Tracy Profiler - www.github.com/wolfpld/tracy",
|
||||
"Ogg and Vorbis - Xiph.org Foundation",
|
||||
"OpenAL Soft - www.github.com/kcat/openal-soft",
|
||||
"OpenFBX - www.github.com/nem0/OpenFBX",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user