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

# Conflicts:
#	Source/Engine/Content/JsonAsset.cpp
This commit is contained in:
Wojciech Figat
2022-10-19 13:36:46 +02:00
32 changed files with 362 additions and 98 deletions

View File

@@ -536,15 +536,6 @@ namespace FlaxEditor.Content.GUI
} }
} }
/// <summary>
/// Called when user wants to rename item.
/// </summary>
/// <param name="item">The item.</param>
public void OnItemDoubleClickName(ContentItem item)
{
OnRename?.Invoke(item);
}
/// <summary> /// <summary>
/// Called when user wants to open item. /// Called when user wants to open item.
/// </summary> /// </summary>

View File

@@ -691,17 +691,8 @@ namespace FlaxEditor.Content
{ {
Focus(); Focus();
// Check if clicked on name area (and can be renamed)
if (CanRename && TextRectangle.Contains(ref location))
{
// Rename
(Parent as ContentView).OnItemDoubleClickName(this);
}
else
{
// Open // Open
(Parent as ContentView).OnItemDoubleClick(this); (Parent as ContentView).OnItemDoubleClick(this);
}
return true; return true;
} }

View File

@@ -95,11 +95,19 @@ namespace FlaxEditor.Content
{ {
if (!_folder.CanRename) if (!_folder.CanRename)
return; return;
Editor.Instance.Windows.ContentWin.ScrollingOnTreeView(false);
// Start renaming the folder // Start renaming the folder
var dialog = RenamePopup.Show(this, HeaderRect, _folder.ShortName, false); var dialog = RenamePopup.Show(this, HeaderRect, _folder.ShortName, false);
dialog.Tag = _folder; dialog.Tag = _folder;
dialog.Renamed += popup => Editor.Instance.Windows.ContentWin.Rename((ContentFolder)popup.Tag, popup.Text); dialog.Renamed += popup =>
{
Editor.Instance.Windows.ContentWin.Rename((ContentFolder)popup.Tag, popup.Text);
Editor.Instance.Windows.ContentWin.ScrollingOnTreeView(true);
};
dialog.Closed += popup =>
{
Editor.Instance.Windows.ContentWin.ScrollingOnTreeView(true);
};
} }
/// <summary> /// <summary>

View File

@@ -24,7 +24,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
public override void Initialize(LayoutElementsContainer layout) public override void Initialize(LayoutElementsContainer layout)
{ {
string[] layerNames = LayersAndTagsSettings.GetCurrentLayers(); string[] layerNames = LayersAndTagsSettings.GetCurrentLayers();
int layersCount = Math.Max(4, layerNames.Length); int layersCount = layerNames.Length;
_checkBoxes = new List<CheckBox>(); _checkBoxes = new List<CheckBox>();
_layersCount = layersCount; _layersCount = layersCount;

View File

@@ -22,7 +22,7 @@ namespace FlaxEditor.CustomEditors.Elements
/// <summary> /// <summary>
/// [Deprecated on 26.05.2022, expires on 26.05.2024] /// [Deprecated on 26.05.2022, expires on 26.05.2024]
/// </summary> /// </summary>
[System.Obsolete("Deprecated in 1.4")] [System.Obsolete("Deprecated in 1.4, ValueBox instead")]
public FloatValueBox FloatValue => ValueBox; public FloatValueBox FloatValue => ValueBox;
/// <summary> /// <summary>

View File

@@ -56,6 +56,7 @@ namespace FlaxEditor.GUI.Input
private Float2 _startSlideLocation; private Float2 _startSlideLocation;
private double _clickStartTime = -1; private double _clickStartTime = -1;
private bool _cursorChanged;
/// <summary> /// <summary>
/// Occurs when value gets changed. /// Occurs when value gets changed.
@@ -172,6 +173,11 @@ namespace FlaxEditor.GUI.Input
{ {
_isSliding = false; _isSliding = false;
EndMouseCapture(); EndMouseCapture();
if (_cursorChanged)
{
Cursor = CursorType.Default;
_cursorChanged = false;
}
SlidingEnd?.Invoke(); SlidingEnd?.Invoke();
} }
@@ -223,6 +229,8 @@ namespace FlaxEditor.GUI.Input
UpdateText(); UpdateText();
} }
Cursor = CursorType.Default;
ResetViewOffset(); ResetViewOffset();
} }
@@ -236,6 +244,8 @@ namespace FlaxEditor.GUI.Input
_startSlideLocation = location; _startSlideLocation = location;
_startSlideValue = _value; _startSlideValue = _value;
StartMouseCapture(true); StartMouseCapture(true);
Cursor = CursorType.SizeWE;
_cursorChanged = true;
SlidingStart?.Invoke(); SlidingStart?.Invoke();
return true; return true;
} }
@@ -249,7 +259,7 @@ namespace FlaxEditor.GUI.Input
/// <inheritdoc /> /// <inheritdoc />
public override void OnMouseMove(Float2 location) public override void OnMouseMove(Float2 location)
{ {
if (_isSliding) if (_isSliding && !RootWindow.Window.IsMouseFlippingHorizontally)
{ {
// Update sliding // Update sliding
var slideLocation = location + Root.TrackingMouseOffset; var slideLocation = location + Root.TrackingMouseOffset;
@@ -257,6 +267,18 @@ namespace FlaxEditor.GUI.Input
return; return;
} }
// Update cursor type so user knows they can slide value
if (CanUseSliding && SlideRect.Contains(location))
{
Cursor = CursorType.SizeWE;
_cursorChanged = true;
}
else if (_cursorChanged && !_isSliding)
{
Cursor = CursorType.Default;
_cursorChanged = false;
}
base.OnMouseMove(location); base.OnMouseMove(location);
} }
@@ -281,6 +303,18 @@ namespace FlaxEditor.GUI.Input
return base.OnMouseUp(location, button); return base.OnMouseUp(location, button);
} }
/// <inheritdoc />
public override void OnMouseLeave()
{
if (_cursorChanged)
{
Cursor = CursorType.Default;
_cursorChanged = false;
}
base.OnMouseLeave();
}
/// <inheritdoc /> /// <inheritdoc />
protected override void OnEditBegin() protected override void OnEditBegin()
{ {

View File

@@ -69,10 +69,10 @@ namespace FlaxEditor.GUI.Timeline.GUI
/// <inheritdoc /> /// <inheritdoc />
public override void OnMouseMove(Float2 location) public override void OnMouseMove(Float2 location)
{ {
if (_isMoving) if (_isMoving && !_timeline.RootWindow.Window.IsMouseFlippingHorizontally)
{ {
var moveLocation = Root.MousePosition; var moveLocation = Root.MousePosition;
var moveLocationDelta = moveLocation - _startMoveLocation; var moveLocationDelta = moveLocation - _startMoveLocation + _timeline.Root.TrackingMouseOffset.X;
var moveDelta = (int)(moveLocationDelta.X / (Timeline.UnitsPerSecond * _timeline.Zoom) * _timeline.FramesPerSecond); var moveDelta = (int)(moveLocationDelta.X / (Timeline.UnitsPerSecond * _timeline.Zoom) * _timeline.FramesPerSecond);
var durationFrames = _timeline.DurationFrames; var durationFrames = _timeline.DurationFrames;
@@ -83,6 +83,7 @@ namespace FlaxEditor.GUI.Timeline.GUI
else else
{ {
_timeline.DurationFrames = _startMoveDuration + moveDelta; _timeline.DurationFrames = _startMoveDuration + moveDelta;
_timeline.MediaBackground.HScrollBar.Value = _timeline.MediaBackground.HScrollBar.Maximum;
} }
if (_timeline.DurationFrames != durationFrames) if (_timeline.DurationFrames != durationFrames)
@@ -140,6 +141,7 @@ namespace FlaxEditor.GUI.Timeline.GUI
_timeline.DurationFrames = duration; _timeline.DurationFrames = duration;
} }
_isMoving = false; _isMoving = false;
_timeline.MediaBackground.HScrollBar.Value = _timeline.MediaBackground.HScrollBar.Maximum;
EndMouseCapture(); EndMouseCapture();
} }

View File

@@ -273,15 +273,26 @@ namespace FlaxEditor.SceneGraph.GUI
Select(); Select();
// Disable scrolling of scene view
Editor.Instance.Windows.SceneWin.ScrollingOnSceneTreeView(false);
// Start renaming the actor // Start renaming the actor
var dialog = RenamePopup.Show(this, HeaderRect, _actorNode.Name, false); var dialog = RenamePopup.Show(this, HeaderRect, _actorNode.Name, false);
dialog.Renamed += OnRenamed; dialog.Renamed += OnRenamed;
dialog.Closed += popup =>
{
// Enable scrolling of scene view
Editor.Instance.Windows.SceneWin.ScrollingOnSceneTreeView(true);
};
} }
private void OnRenamed(RenamePopup renamePopup) private void OnRenamed(RenamePopup renamePopup)
{ {
using (new UndoBlock(ActorNode.Root.Undo, Actor, "Rename")) using (new UndoBlock(ActorNode.Root.Undo, Actor, "Rename"))
Actor.Name = renamePopup.Text; Actor.Name = renamePopup.Text;
// Enable scrolling of scene view
Editor.Instance.Windows.SceneWin.ScrollingOnSceneTreeView(true);
} }
/// <inheritdoc /> /// <inheritdoc />

View File

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

View File

@@ -7,6 +7,7 @@ using FlaxEditor.CustomEditors;
using FlaxEditor.CustomEditors.Editors; using FlaxEditor.CustomEditors.Editors;
using FlaxEditor.CustomEditors.Elements; using FlaxEditor.CustomEditors.Elements;
using FlaxEditor.GUI; using FlaxEditor.GUI;
using FlaxEditor.GUI.Tree;
using FlaxEditor.Viewport.Cameras; using FlaxEditor.Viewport.Cameras;
using FlaxEditor.Viewport.Previews; using FlaxEditor.Viewport.Previews;
using FlaxEngine; using FlaxEngine;
@@ -166,8 +167,21 @@ namespace FlaxEditor.Windows.Assets
var proxy = (PropertiesProxy)Values[0]; var proxy = (PropertiesProxy)Values[0];
int nodeIndex = (int)checkBox.Tag; int nodeIndex = (int)checkBox.Tag;
proxy.NodesMask[nodeIndex] = checkBox.Checked; proxy.NodesMask[nodeIndex] = checkBox.Checked;
if (Input.GetKey(KeyboardKeys.Shift))
SetTreeChecked(checkBox.Parent as TreeNode, checkBox.Checked);
proxy.Window.MarkAsEdited(); proxy.Window.MarkAsEdited();
} }
private void SetTreeChecked(TreeNode tree, bool state)
{
foreach (var node in tree.Children)
{
if (node is TreeNode treeNode)
SetTreeChecked(treeNode, state);
else if (node is CheckBox checkBox)
checkBox.Checked = state;
}
}
} }
} }

View File

@@ -27,6 +27,8 @@ namespace FlaxEditor.Windows
private const string ProjectDataLastViewedFolder = "LastViewedFolder"; private const string ProjectDataLastViewedFolder = "LastViewedFolder";
private bool _isWorkspaceDirty; private bool _isWorkspaceDirty;
private SplitPanel _split; private SplitPanel _split;
private Panel _contentViewPanel;
private Panel _contentTreePanel;
private ContentView _view; private ContentView _view;
private readonly ToolStrip _toolStrip; private readonly ToolStrip _toolStrip;
@@ -95,7 +97,7 @@ namespace FlaxEditor.Windows
}; };
// Split panel // Split panel
_split = new SplitPanel(options.Options.Interface.ContentWindowOrientation, ScrollBars.Both, ScrollBars.Vertical) _split = new SplitPanel(options.Options.Interface.ContentWindowOrientation, ScrollBars.None, ScrollBars.None)
{ {
AnchorPreset = AnchorPresets.StretchAll, AnchorPreset = AnchorPresets.StretchAll,
Offsets = new Margin(0, 0, _toolStrip.Bottom, 0), Offsets = new Margin(0, 0, _toolStrip.Bottom, 0),
@@ -120,11 +122,20 @@ namespace FlaxEditor.Windows
}; };
_foldersSearchBox.TextChanged += OnFoldersSearchBoxTextChanged; _foldersSearchBox.TextChanged += OnFoldersSearchBoxTextChanged;
// Content tree panel
_contentTreePanel = new Panel
{
AnchorPreset = AnchorPresets.StretchAll,
Offsets = new Margin(0, 0, headerPanel.Bottom, 0),
IsScrollable = true,
ScrollBars = ScrollBars.Both,
Parent = _split.Panel1,
};
// Content structure tree // Content structure tree
_tree = new Tree(false) _tree = new Tree(false)
{ {
Y = headerPanel.Bottom, Parent = _contentTreePanel,
Parent = _split.Panel1,
}; };
_tree.SelectedChanged += OnTreeSelectionChanged; _tree.SelectedChanged += OnTreeSelectionChanged;
headerPanel.Parent = _split.Panel1; headerPanel.Parent = _split.Panel1;
@@ -159,13 +170,23 @@ namespace FlaxEditor.Windows
_viewDropdown.Items.Add(((ContentItemSearchFilter)i).ToString()); _viewDropdown.Items.Add(((ContentItemSearchFilter)i).ToString());
_viewDropdown.PopupCreate += OnViewDropdownPopupCreate; _viewDropdown.PopupCreate += OnViewDropdownPopupCreate;
// Content view panel
_contentViewPanel = new Panel
{
AnchorPreset = AnchorPresets.StretchAll,
Offsets = new Margin(0, 0, contentItemsSearchPanel.Bottom + 4, 0),
IsScrollable = true,
ScrollBars = ScrollBars.Vertical,
Parent = _split.Panel2,
};
// Content View // Content View
_view = new ContentView _view = new ContentView
{ {
AnchorPreset = AnchorPresets.HorizontalStretchTop, AnchorPreset = AnchorPresets.HorizontalStretchTop,
Offsets = new Margin(0, 0, contentItemsSearchPanel.Bottom + 4, 0), Offsets = new Margin(0, 0, 0, 0),
IsScrollable = true, IsScrollable = true,
Parent = _split.Panel2, Parent = _contentViewPanel,
}; };
_view.OnOpen += Open; _view.OnOpen += Open;
_view.OnNavigateBack += NavigateBackward; _view.OnNavigateBack += NavigateBackward;
@@ -271,6 +292,30 @@ namespace FlaxEditor.Windows
RefreshView(SelectedNode); RefreshView(SelectedNode);
} }
/// <summary>
/// Enables or disables vertical and horizontal scrolling on the content tree panel
/// </summary>
/// <param name="enabled">The state to set scrolling to</param>
public void ScrollingOnTreeView(bool enabled)
{
if (_contentTreePanel.VScrollBar != null)
_contentTreePanel.VScrollBar.ThumbEnabled = enabled;
if (_contentTreePanel.HScrollBar != null)
_contentTreePanel.HScrollBar.ThumbEnabled = enabled;
}
/// <summary>
/// Enables or disables vertical and horizontal scrolling on the content view panel
/// </summary>
/// <param name="enabled">The state to set scrolling to</param>
public void ScrollingOnContentView(bool enabled)
{
if (_contentViewPanel.VScrollBar != null)
_contentViewPanel.VScrollBar.ThumbEnabled = enabled;
if (_contentViewPanel.HScrollBar != null)
_contentViewPanel.HScrollBar.ThumbEnabled = enabled;
}
/// <summary> /// <summary>
/// Shows popup dialog with UI to rename content item. /// Shows popup dialog with UI to rename content item.
/// </summary> /// </summary>
@@ -285,6 +330,7 @@ namespace FlaxEditor.Windows
_split.Panel2.VScrollBar.ThumbEnabled = false; _split.Panel2.VScrollBar.ThumbEnabled = false;
if (_split.Panel2.HScrollBar != null) if (_split.Panel2.HScrollBar != null)
_split.Panel2.HScrollBar.ThumbEnabled = false; _split.Panel2.HScrollBar.ThumbEnabled = false;
ScrollingOnContentView(false);
// Show rename popup // Show rename popup
var popup = RenamePopup.Show(item, item.TextRectangle, item.ShortName, true); var popup = RenamePopup.Show(item, item.TextRectangle, item.ShortName, true);
@@ -298,6 +344,7 @@ namespace FlaxEditor.Windows
_split.Panel2.VScrollBar.ThumbEnabled = true; _split.Panel2.VScrollBar.ThumbEnabled = true;
if (_split.Panel2.HScrollBar != null) if (_split.Panel2.HScrollBar != null)
_split.Panel2.HScrollBar.ThumbEnabled = true; _split.Panel2.HScrollBar.ThumbEnabled = true;
ScrollingOnContentView(true);
// Check if was creating new element // Check if was creating new element
if (_newElement != null) if (_newElement != null)

View File

@@ -131,6 +131,7 @@ namespace FlaxEditor.Windows
private TextBox _searchBox; private TextBox _searchBox;
private Tree _tree; private Tree _tree;
private Panel _sceneTreePanel;
private bool _isUpdatingSelection; private bool _isUpdatingSelection;
private bool _isMouseDown; private bool _isMouseDown;
@@ -143,10 +144,9 @@ namespace FlaxEditor.Windows
/// </summary> /// </summary>
/// <param name="editor">The editor.</param> /// <param name="editor">The editor.</param>
public SceneTreeWindow(Editor editor) public SceneTreeWindow(Editor editor)
: base(editor, true, ScrollBars.Both) : base(editor, true, ScrollBars.None)
{ {
Title = "Scene"; Title = "Scene";
ScrollMargin = new Margin(0, 0, 0, 100.0f);
// Scene searching query input box // Scene searching query input box
var headerPanel = new ContainerControl var headerPanel = new ContainerControl
@@ -165,19 +165,29 @@ namespace FlaxEditor.Windows
}; };
_searchBox.TextChanged += OnSearchBoxTextChanged; _searchBox.TextChanged += OnSearchBoxTextChanged;
// Scene tree panel
_sceneTreePanel = new Panel
{
AnchorPreset = AnchorPresets.StretchAll,
Offsets = new Margin(0, 0, headerPanel.Bottom, 0),
IsScrollable = true,
ScrollBars = ScrollBars.Both,
Parent = this,
};
// Create scene structure tree // Create scene structure tree
var root = editor.Scene.Root; var root = editor.Scene.Root;
root.TreeNode.ChildrenIndent = 0; root.TreeNode.ChildrenIndent = 0;
root.TreeNode.Expand(); root.TreeNode.Expand();
_tree = new Tree(true) _tree = new Tree(true)
{ {
Y = headerPanel.Bottom,
Margin = new Margin(0.0f, 0.0f, -16.0f, 0.0f), // Hide root node Margin = new Margin(0.0f, 0.0f, -16.0f, 0.0f), // Hide root node
IsScrollable = true,
}; };
_tree.AddChild(root.TreeNode); _tree.AddChild(root.TreeNode);
_tree.SelectedChanged += Tree_OnSelectedChanged; _tree.SelectedChanged += Tree_OnSelectedChanged;
_tree.RightClick += OnTreeRightClick; _tree.RightClick += OnTreeRightClick;
_tree.Parent = this; _tree.Parent = _sceneTreePanel;
headerPanel.Parent = this; headerPanel.Parent = this;
// Setup input actions // Setup input actions
@@ -188,6 +198,18 @@ namespace FlaxEditor.Windows
InputActions.Add(options => options.Rename, Rename); InputActions.Add(options => options.Rename, Rename);
} }
/// <summary>
/// Enables or disables vertical and horizontal scrolling on the scene tree panel.
/// </summary>
/// <param name="enabled">The state to set scrolling to</param>
public void ScrollingOnSceneTreeView(bool enabled)
{
if (_sceneTreePanel.VScrollBar != null)
_sceneTreePanel.VScrollBar.ThumbEnabled = enabled;
if (_sceneTreePanel.HScrollBar != null)
_sceneTreePanel.HScrollBar.ThumbEnabled = enabled;
}
private void OnSearchBoxTextChanged() private void OnSearchBoxTextChanged()
{ {
// Skip events during setup or init stuff // Skip events during setup or init stuff

View File

@@ -72,7 +72,7 @@ public:
/// If checked, Environment Probes will use HDR texture format. Improves quality in very bright scenes at cost of higher memory usage. /// If checked, Environment Probes will use HDR texture format. Improves quality in very bright scenes at cost of higher memory usage.
/// </summary> /// </summary>
API_FIELD(Attributes = "EditorOrder(1502), EditorDisplay(\"Quality\")") API_FIELD(Attributes = "EditorOrder(1502), EditorDisplay(\"Quality\")")
bool UeeHDRProbes = false; bool UseHDRProbes = false;
/// <summary> /// <summary>
/// If checked, enables Global SDF rendering. This can be used in materials, shaders, and particles. /// If checked, enables Global SDF rendering. This can be used in materials, shaders, and particles.
@@ -118,6 +118,21 @@ public:
API_FIELD(Attributes="EditorOrder(10000), EditorDisplay(\"Post Process Settings\", EditorDisplayAttribute.InlineStyle)") API_FIELD(Attributes="EditorOrder(10000), EditorDisplay(\"Post Process Settings\", EditorDisplayAttribute.InlineStyle)")
PostProcessSettings PostProcessSettings; PostProcessSettings PostProcessSettings;
private:
/// <summary>
/// Renamed UeeHDRProbes into UseHDRProbes
/// [Deprecated on 12.10.2022, expires on 12.10.2024]
/// </summary>
API_PROPERTY(Attributes="Serialize, Obsolete, NoUndo") bool GetUeeHDRProbes() const
{
return UseHDRProbes;
}
API_PROPERTY(Attributes="Serialize, Obsolete, NoUndo") void SetUeeHDRProbes(bool value)
{
UseHDRProbes = value;
}
public: public:
/// <summary> /// <summary>
/// Gets the instance of the settings asset (default value if missing). Object returned by this method is always loaded with valid data to use. /// Gets the instance of the settings asset (default value if missing). Object returned by this method is always loaded with valid data to use.

View File

@@ -120,6 +120,25 @@ void Camera::ProjectPoint(const Vector3& worldSpaceLocation, Float2& cameraViewp
cameraViewportSpaceLocation = Float2(clipSpaceLocation); cameraViewportSpaceLocation = Float2(clipSpaceLocation);
} }
bool Camera::IsPointOnView(const Vector3& worldSpaceLocation) const
{
Vector3 cameraUp = GetTransform().GetUp();
Vector3 cameraForward = GetTransform().GetForward();
Vector3 directionToPosition = (worldSpaceLocation - GetPosition()).GetNormalized();
if (Vector3::Dot(cameraForward, directionToPosition) < 0)
return false;
Quaternion lookAt = Quaternion::LookRotation(directionToPosition, cameraUp);
Vector3 lookAtDirection = lookAt * Vector3::Forward;
Vector3 newWorldLocation = GetPosition() + lookAtDirection;
Float2 windowSpace;
const Viewport viewport = GetViewport();
ProjectPoint(newWorldLocation, windowSpace, viewport);
return windowSpace.X >= 0 && windowSpace.X <= viewport.Size.X && windowSpace.Y >= 0 && windowSpace.Y <= viewport.Size.Y;
}
Ray Camera::ConvertMouseToRay(const Float2& mousePosition) const Ray Camera::ConvertMouseToRay(const Float2& mousePosition) const
{ {
return ConvertMouseToRay(mousePosition, GetViewport()); return ConvertMouseToRay(mousePosition, GetViewport());

View File

@@ -168,6 +168,13 @@ public:
/// <param name="viewport">The viewport.</param> /// <param name="viewport">The viewport.</param>
API_FUNCTION() void ProjectPoint(const Vector3& worldSpaceLocation, API_PARAM(Out) Float2& cameraViewportSpaceLocation, API_PARAM(Ref) const Viewport& viewport) const; API_FUNCTION() void ProjectPoint(const Vector3& worldSpaceLocation, API_PARAM(Out) Float2& cameraViewportSpaceLocation, API_PARAM(Ref) const Viewport& viewport) const;
/// <summary>
/// Checks if the 3d point of the world is in the camera's field of view.
/// </summary>
/// <param name="worldSpaceLocation">World Position (XYZ).</param>
/// <returns>Returns true if the point is within the field of view.</returns>
API_FUNCTION() bool IsPointOnView(const Vector3& worldSpaceLocation) const;
/// <summary> /// <summary>
/// Converts the mouse position to 3D ray. /// Converts the mouse position to 3D ray.
/// </summary> /// </summary>

View File

@@ -287,6 +287,8 @@ protected:
bool _isUsingMouseOffset; bool _isUsingMouseOffset;
Rectangle _mouseOffsetScreenSize; Rectangle _mouseOffsetScreenSize;
bool _isTrackingMouse; bool _isTrackingMouse;
bool _isHorizontalFlippingMouse;
bool _isVerticalFlippingMouse;
bool _isClippingCursor; bool _isClippingCursor;
explicit WindowBase(const CreateWindowSettings& settings); explicit WindowBase(const CreateWindowSettings& settings);
@@ -680,6 +682,22 @@ public:
return _isTrackingMouse; return _isTrackingMouse;
} }
/// <summary>
/// Gets the value indicating if the mouse flipped to the other screen edge horizontally
/// </summary>
API_PROPERTY() bool IsMouseFlippingHorizontally() const
{
return _isHorizontalFlippingMouse;
}
/// <summary>
/// Gets the value indicating if the mouse flipped to the other screen edge vertically
/// </summary>
API_PROPERTY() bool IsMouseFlippingVertically() const
{
return _isVerticalFlippingMouse;
}
/// <summary> /// <summary>
/// Ends the mouse tracking. /// Ends the mouse tracking.
/// </summary> /// </summary>

View File

@@ -1,5 +1,8 @@
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved. // Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
using System;
using FlaxEngine;
namespace FlaxEditor.Content.Settings namespace FlaxEditor.Content.Settings
{ {
/// <summary> /// <summary>
@@ -11,13 +14,24 @@ namespace FlaxEditor.Content.Settings
partial class GraphicsSettings partial class GraphicsSettings
{ {
/// <summary>
/// Renamed UeeHDRProbes into UseHDRProbes
/// [Deprecated on 12.10.2022, expires on 12.10.2024]
/// </summary>
[Serialize, Obsolete, NoUndo]
private bool UeeHDRProbes
{
get => UseHDRProbes;
set => UseHDRProbes = value;
}
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="GraphicsSettings"/>. /// Initializes a new instance of the <see cref="GraphicsSettings"/>.
/// </summary> /// </summary>
public GraphicsSettings() public GraphicsSettings()
{ {
// Initialize PostFx settings with default options (C# structs don't support it) // Initialize PostFx settings with default options (C# structs don't support it)
PostProcessSettings = FlaxEngine.PostProcessSettings.Default; PostProcessSettings = PostProcessSettings.Default;
} }
} }
} }

View File

@@ -544,6 +544,8 @@ void WindowsWindow::StartTrackingMouse(bool useMouseScreenOffset)
_isTrackingMouse = true; _isTrackingMouse = true;
_trackingMouseOffset = Float2::Zero; _trackingMouseOffset = Float2::Zero;
_isUsingMouseOffset = useMouseScreenOffset; _isUsingMouseOffset = useMouseScreenOffset;
_isHorizontalFlippingMouse = false;
_isVerticalFlippingMouse = false;
int32 x = 0, y = 0, width = 0, height = 0; int32 x = 0, y = 0, width = 0, height = 0;
GetScreenInfo(x, y, width, height); GetScreenInfo(x, y, width, height);
@@ -558,6 +560,8 @@ void WindowsWindow::EndTrackingMouse()
if (_isTrackingMouse) if (_isTrackingMouse)
{ {
_isTrackingMouse = false; _isTrackingMouse = false;
_isHorizontalFlippingMouse = false;
_isVerticalFlippingMouse = false;
ReleaseCapture(); ReleaseCapture();
} }
@@ -824,14 +828,14 @@ LRESULT WindowsWindow::WndProc(UINT msg, WPARAM wParam, LPARAM lParam)
const Float2 mousePos(static_cast<float>(WINDOWS_GET_X_LPARAM(lParam)), static_cast<float>(WINDOWS_GET_Y_LPARAM(lParam))); const Float2 mousePos(static_cast<float>(WINDOWS_GET_X_LPARAM(lParam)), static_cast<float>(WINDOWS_GET_Y_LPARAM(lParam)));
Float2 mousePosition = ClientToScreen(mousePos); Float2 mousePosition = ClientToScreen(mousePos);
Float2 newMousePosition = mousePosition; Float2 newMousePosition = mousePosition;
if (mousePosition.X <= desktopLocation.X + 2) if (_isHorizontalFlippingMouse = mousePosition.X <= desktopLocation.X + 2)
newMousePosition.X = desktopSize.X - 2; newMousePosition.X = desktopSize.X - 3;
else if (mousePosition.X >= desktopSize.X - 1) else if (_isHorizontalFlippingMouse = mousePosition.X >= desktopSize.X - 1)
newMousePosition.X = desktopLocation.X + 2; newMousePosition.X = desktopLocation.X + 3;
if (mousePosition.Y <= desktopLocation.Y + 2) if (_isVerticalFlippingMouse = mousePosition.Y <= desktopLocation.Y + 2)
newMousePosition.Y = desktopSize.Y - 2; newMousePosition.Y = desktopSize.Y - 3;
else if (mousePosition.Y >= desktopSize.Y - 1) else if (_isVerticalFlippingMouse = mousePosition.Y >= desktopSize.Y - 1)
newMousePosition.Y = desktopLocation.Y + 2; newMousePosition.Y = desktopLocation.Y + 3;
if (!Float2::NearEqual(mousePosition, newMousePosition)) if (!Float2::NearEqual(mousePosition, newMousePosition))
{ {
_trackingMouseOffset -= newMousePosition - mousePosition; _trackingMouseOffset -= newMousePosition - mousePosition;

View File

@@ -204,7 +204,7 @@ int32 ProbesRenderer::Entry::GetResolution() const
PixelFormat ProbesRenderer::Entry::GetFormat() const PixelFormat ProbesRenderer::Entry::GetFormat() const
{ {
return GraphicsSettings::Get()->UeeHDRProbes ? PixelFormat::R11G11B10_Float : PixelFormat::R8G8B8A8_UNorm; return GraphicsSettings::Get()->UseHDRProbes ? PixelFormat::R11G11B10_Float : PixelFormat::R8G8B8A8_UNorm;
} }
int32 ProbesRenderer::GetBakeQueueSize() int32 ProbesRenderer::GetBakeQueueSize()

View File

@@ -948,6 +948,10 @@ namespace FlaxEngine.GUI
{ {
// Set flag // Set flag
_isDragOver = true; _isDragOver = true;
// Hide tooltip
Tooltip?.Hide();
return DragDropEffect.None; return DragDropEffect.None;
} }

View File

@@ -23,6 +23,7 @@ namespace FlaxEngine.GUI
private float _splitterValue; private float _splitterValue;
private Rectangle _splitterRect; private Rectangle _splitterRect;
private bool _splitterClicked, _mouseOverSplitter; private bool _splitterClicked, _mouseOverSplitter;
private bool _cursorChanged;
/// <summary> /// <summary>
/// The first panel (left or upper based on Orientation). /// The first panel (left or upper based on Orientation).
@@ -161,6 +162,18 @@ namespace FlaxEngine.GUI
if (_splitterClicked) if (_splitterClicked)
{ {
SplitterValue = _orientation == Orientation.Horizontal ? location.X / Width : location.Y / Height; SplitterValue = _orientation == Orientation.Horizontal ? location.X / Width : location.Y / Height;
Cursor = _orientation == Orientation.Horizontal ? CursorType.SizeWE : CursorType.SizeNS;
_cursorChanged = true;
}
else if (_mouseOverSplitter)
{
Cursor = _orientation == Orientation.Horizontal ? CursorType.SizeWE : CursorType.SizeNS;
_cursorChanged = true;
}
else if (_cursorChanged)
{
Cursor = CursorType.Default;
_cursorChanged = false;
} }
base.OnMouseMove(location); base.OnMouseMove(location);
@@ -197,6 +210,11 @@ namespace FlaxEngine.GUI
{ {
// Clear flag // Clear flag
_mouseOverSplitter = false; _mouseOverSplitter = false;
if (_cursorChanged)
{
Cursor = CursorType.Default;
_cursorChanged = false;
}
base.OnMouseLeave(); base.OnMouseLeave();
} }

View File

@@ -922,10 +922,8 @@ namespace Flax.Build.Bindings
// Properties // Properties
foreach (var propertyInfo in classInfo.Properties) foreach (var propertyInfo in classInfo.Properties)
{ {
if (propertyInfo.IsHidden) if (propertyInfo.IsHidden || !useUnmanaged)
continue; continue;
if (!useUnmanaged)
throw new NotImplementedException("TODO: support properties inside non-static and non-scripting API class types.");
contents.AppendLine(); contents.AppendLine();
GenerateCSharpComment(contents, indent, propertyInfo.Comment, true); GenerateCSharpComment(contents, indent, propertyInfo.Comment, true);

View File

@@ -1446,6 +1446,11 @@ namespace Flax.Build.Bindings
continue; continue;
if (GenerateCppAutoSerializationSkip(buildData, typeInfo, propertyInfo, propertyInfo.Type)) if (GenerateCppAutoSerializationSkip(buildData, typeInfo, propertyInfo, propertyInfo.Type))
continue; continue;
CppAutoSerializeProperties.Add(propertyInfo);
// Skip writing deprecated properties (read-only deserialization to allow reading old data)
if (propertyInfo.HasAttribute("Obsolete"))
continue;
contents.Append(" {"); contents.Append(" {");
contents.Append(" const auto"); contents.Append(" const auto");
@@ -1462,7 +1467,6 @@ namespace Flax.Build.Bindings
contents.Append($"stream.JKEY(\"{propertyInfo.Name}\"); Serialization::Serialize(stream, value, nullptr);"); contents.Append($"stream.JKEY(\"{propertyInfo.Name}\"); Serialization::Serialize(stream, value, nullptr);");
contents.Append(" }"); contents.Append(" }");
contents.Append('}').AppendLine(); contents.Append('}').AppendLine();
CppAutoSerializeProperties.Add(propertyInfo);
} }
} }
else if (structureInfo != null) else if (structureInfo != null)
@@ -1494,14 +1498,14 @@ namespace Flax.Build.Bindings
foreach (var propertyInfo in CppAutoSerializeProperties) foreach (var propertyInfo in CppAutoSerializeProperties)
{ {
contents.Append(" {"); contents.AppendLine(" {");
contents.Append($" const auto e = SERIALIZE_FIND_MEMBER(stream, \"{propertyInfo.Name}\");"); contents.AppendLine($" const auto e = SERIALIZE_FIND_MEMBER(stream, \"{propertyInfo.Name}\");");
contents.Append(" if (e != stream.MemberEnd()) {"); contents.AppendLine(" if (e != stream.MemberEnd()) {");
contents.Append($" auto p = {propertyInfo.Getter.Name}();"); contents.AppendLine($" auto p = {propertyInfo.Getter.Name}();");
contents.Append(" Serialization::Deserialize(e->value, p, modifier);"); contents.AppendLine(" Serialization::Deserialize(e->value, p, modifier);");
contents.Append($" {propertyInfo.Setter.Name}(p);"); contents.AppendLine($" {propertyInfo.Setter.Name}(p);");
contents.Append(" }"); contents.AppendLine(" }");
contents.Append('}').AppendLine(); contents.AppendLine(" }");
} }
contents.Append('}').AppendLine(); contents.Append('}').AppendLine();

View File

@@ -435,7 +435,7 @@ namespace Flax.Build
else if (dependencyModule.BinaryModuleName == "FlaxEngine") else if (dependencyModule.BinaryModuleName == "FlaxEngine")
{ {
// TODO: instead of this hack find a way to reference the prebuilt target bindings binary (example: game C# project references FlaxEngine C# prebuilt dll) // TODO: instead of this hack find a way to reference the prebuilt target bindings binary (example: game C# project references FlaxEngine C# prebuilt dll)
project.CSharp.FileReferences.Add(Path.Combine(Globals.EngineRoot, "Binaries/Editor/Win64/Development/FlaxEngine.CSharp.dll")); project.CSharp.FileReferences.Add(Path.Combine(Globals.EngineRoot, Platform.GetEditorBinaryDirectory(), "Development/FlaxEngine.CSharp.dll"));
} }
} }
} }

View File

@@ -245,6 +245,24 @@ namespace Flax.Build
return toolchain; return toolchain;
} }
/// <summary>
/// Gets path to the current platform binary directory
/// </summary>
public static string GetEditorBinaryDirectory()
{
var subdir = "Binaries/Editor/";
switch (Platform.BuildTargetPlatform)
{
case TargetPlatform.Windows:
return subdir + "Win64";
case TargetPlatform.Linux:
return subdir + "Linux";
case TargetPlatform.Mac:
return subdir + "Mac";
}
throw new NotImplementedException();
}
/// <summary> /// <summary>
/// Creates the project files generator for the specified project format. /// Creates the project files generator for the specified project format.
/// </summary> /// </summary>

View File

@@ -39,6 +39,12 @@ namespace Flax.Build
[CommandLine("deploy", "Runs the deploy tool.")] [CommandLine("deploy", "Runs the deploy tool.")]
public static bool Deploy = false; public static bool Deploy = false;
/// <summary>
/// Compresses deployed files.
/// </summary>
[CommandLine("deployDontCompress", "Skips compressing deployed files, and keeps files.")]
public static bool DontCompress = false;
/// <summary> /// <summary>
/// Builds the targets. Builds all the targets, use <see cref="BuildTargets"/> to select a custom set of targets for the build. /// Builds the targets. Builds all the targets, use <see cref="BuildTargets"/> to select a custom set of targets for the build.
/// </summary> /// </summary>

View File

@@ -7,6 +7,7 @@ using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using Flax.Build; using Flax.Build;
using Flax.Build.Platforms;
namespace Flax.Deploy namespace Flax.Deploy
{ {
@@ -126,21 +127,24 @@ namespace Flax.Deploy
DeployFile(RootPath, OutputPath, "Flax.flaxproj"); DeployFile(RootPath, OutputPath, "Flax.flaxproj");
// Compress // Compress
if (Configuration.DontCompress)
return;
Log.Info(string.Empty); Log.Info(string.Empty);
Log.Info("Compressing editor files..."); Log.Info("Compressing editor files...");
string editorPackageZipPath; string editorPackageZipPath;
if (Platform.BuildTargetPlatform == TargetPlatform.Linux) var unix = Platform.BuildTargetPlatform == TargetPlatform.Linux || Platform.BuildTargetPlatform == TargetPlatform.Mac;
if (unix)
{ {
// Use system tool (preserves executable file attributes and link files) var zipEofPath = UnixPlatform.Which("zip");
editorPackageZipPath = Path.Combine(Deployer.PackageOutputPath, "FlaxEditorLinux.zip"); unix = File.Exists(zipEofPath);
Utilities.FileDelete(editorPackageZipPath); if (!unix)
Utilities.Run("zip", "Editor.zip -r .", null, OutputPath, Utilities.RunOptions.ThrowExceptionOnError); Log.Verbose("Using .NET compressing");
File.Move(Path.Combine(OutputPath, "Editor.zip"), editorPackageZipPath);
} }
else if (Platform.BuildTargetPlatform == TargetPlatform.Mac) if (unix)
{ {
// Use system tool (preserves executable file attributes and link files) // Use system tool (preserves executable file attributes and link files)
editorPackageZipPath = Path.Combine(Deployer.PackageOutputPath, "FlaxEditorMac.zip"); editorPackageZipPath = Path.Combine(Deployer.PackageOutputPath, $"FlaxEditor{Enum.GetName(typeof(TargetPlatform), Platform.BuildTargetPlatform)}.zip");
Utilities.FileDelete(editorPackageZipPath); Utilities.FileDelete(editorPackageZipPath);
Utilities.Run("zip", "Editor.zip -r .", null, OutputPath, Utilities.RunOptions.ThrowExceptionOnError); Utilities.Run("zip", "Editor.zip -r .", null, OutputPath, Utilities.RunOptions.ThrowExceptionOnError);
File.Move(Path.Combine(OutputPath, "Editor.zip"), editorPackageZipPath); File.Move(Path.Combine(OutputPath, "Editor.zip"), editorPackageZipPath);
@@ -189,13 +193,14 @@ namespace Flax.Deploy
private static void DeployEditorBinaries(TargetConfiguration configuration) private static void DeployEditorBinaries(TargetConfiguration configuration)
{ {
if (Platform.BuildTargetPlatform == TargetPlatform.Windows) var binariesSubDir = Path.Combine(Platform.GetEditorBinaryDirectory(), configuration.ToString());
{
var binariesSubDir = "Binaries/Editor/Win64/" + configuration;
var src = Path.Combine(RootPath, binariesSubDir); var src = Path.Combine(RootPath, binariesSubDir);
var dst = Path.Combine(OutputPath, binariesSubDir); var dst = Path.Combine(OutputPath, binariesSubDir);
var dstDebug = Path.Combine(Deployer.PackageOutputPath, "EditorDebugSymbols/Win64/" + configuration);
Directory.CreateDirectory(dst); Directory.CreateDirectory(dst);
if (Platform.BuildTargetPlatform == TargetPlatform.Windows)
{
var dstDebug = Path.Combine(Deployer.PackageOutputPath, "EditorDebugSymbols/Win64/" + configuration);
Directory.CreateDirectory(dstDebug); Directory.CreateDirectory(dstDebug);
// Validate that build editor app has a valid version number // Validate that build editor app has a valid version number
@@ -229,11 +234,6 @@ namespace Flax.Deploy
} }
else if (Platform.BuildTargetPlatform == TargetPlatform.Linux) else if (Platform.BuildTargetPlatform == TargetPlatform.Linux)
{ {
var binariesSubDir = "Binaries/Editor/Linux/" + configuration;
var src = Path.Combine(RootPath, binariesSubDir);
var dst = Path.Combine(OutputPath, binariesSubDir);
Directory.CreateDirectory(dst);
// Deploy binaries // Deploy binaries
DeployFile(src, dst, "FlaxEditor"); DeployFile(src, dst, "FlaxEditor");
DeployFile(src, dst, "FlaxEditor.Build.json"); DeployFile(src, dst, "FlaxEditor.Build.json");
@@ -253,11 +253,6 @@ namespace Flax.Deploy
} }
else if (Platform.BuildTargetPlatform == TargetPlatform.Mac) else if (Platform.BuildTargetPlatform == TargetPlatform.Mac)
{ {
var binariesSubDir = "Binaries/Editor/Mac/" + configuration;
var src = Path.Combine(RootPath, binariesSubDir);
var dst = Path.Combine(OutputPath, binariesSubDir);
Directory.CreateDirectory(dst);
// Deploy binaries // Deploy binaries
DeployFile(src, dst, "FlaxEditor"); DeployFile(src, dst, "FlaxEditor");
DeployFile(src, dst, "FlaxEditor.Build.json"); DeployFile(src, dst, "FlaxEditor.Build.json");
@@ -274,10 +269,6 @@ namespace Flax.Deploy
Utilities.Run("strip", "libmonosgen-2.0.1.dylib", null, dst, Utilities.RunOptions.None); Utilities.Run("strip", "libmonosgen-2.0.1.dylib", null, dst, Utilities.RunOptions.None);
Utilities.Run("strip", "libMoltenVK.dylib", null, dst, Utilities.RunOptions.None); Utilities.Run("strip", "libMoltenVK.dylib", null, dst, Utilities.RunOptions.None);
} }
else
{
throw new NotImplementedException();
}
} }
} }
} }

View File

@@ -63,6 +63,7 @@ namespace Flax.Deploy
} }
// Compress // Compress
if (!Configuration.DontCompress)
{ {
Log.Info("Compressing platform files..."); Log.Info("Compressing platform files...");
@@ -84,10 +85,10 @@ namespace Flax.Deploy
#endif #endif
Log.Info(string.Format("Compressed {0} package size: {1}", platformName, Utilities.GetFileSize(packageZipPath))); Log.Info(string.Format("Compressed {0} package size: {1}", platformName, Utilities.GetFileSize(packageZipPath)));
}
// Remove files (only zip package is used) // Remove files (only zip package is used)
Utilities.DirectoryDelete(dst); Utilities.DirectoryDelete(dst);
}
Log.Info(string.Empty); Log.Info(string.Empty);
} }

View File

@@ -58,7 +58,7 @@ namespace Flax.Build.Platforms
if (Compiler != null) if (Compiler != null)
{ {
// System compiler // System compiler
ToolchainRoot = string.Empty; ToolchainRoot = "/";
Log.Verbose($"Using native Linux toolchain (compiler {Compiler})"); Log.Verbose($"Using native Linux toolchain (compiler {Compiler})");
HasRequiredSDKsInstalled = true; HasRequiredSDKsInstalled = true;
} }

View File

@@ -23,9 +23,16 @@ namespace Flax.Build.Platforms
: base(platform, architecture, platform.ToolchainRoot, platform.Compiler) : base(platform, architecture, platform.ToolchainRoot, platform.Compiler)
{ {
// Setup system paths // Setup system paths
SystemIncludePaths.Add(Path.Combine(ToolsetRoot, "usr", "include")); var includePath = Path.Combine(ToolsetRoot, "usr", "include");
SystemIncludePaths.Add(Path.Combine(ToolsetRoot, "include", "c++", "5.2.0")); SystemIncludePaths.Add(includePath);
SystemIncludePaths.Add(Path.Combine(ToolsetRoot, "lib", "clang", ClangVersion.Major.ToString(), "include")); var cppIncludePath = Path.Combine(includePath, "c++", ClangVersion.ToString());
if (Directory.Exists(cppIncludePath))
SystemIncludePaths.Add(cppIncludePath);
var clangLibPath = Path.Combine(ToolsetRoot, "usr", "lib", "clang");
var clangIncludePath = Path.Combine(clangLibPath, ClangVersion.Major.ToString(), "include");
if (!Directory.Exists(clangIncludePath))
clangIncludePath = Path.Combine(clangLibPath, ClangVersion.ToString(), "include");
SystemIncludePaths.Add(clangIncludePath);
} }
/// <inheritdoc /> /// <inheritdoc />

View File

@@ -138,7 +138,9 @@ namespace Flax.Build.Projects
default: throw new ArgumentOutOfRangeException(nameof(type), type, null); default: throw new ArgumentOutOfRangeException(nameof(type), type, null);
} }
} }
case ProjectFormat.VisualStudioCode: return new VisualStudioCodeProjectGenerator(); case ProjectFormat.VisualStudioCode: return type == TargetType.DotNet
? (ProjectGenerator)new CSProjectGenerator(VisualStudioVersion.VisualStudio2015)
: (ProjectGenerator)new VisualStudioCodeProjectGenerator();
case ProjectFormat.XCode: return new XCodeProjectGenerator(); case ProjectFormat.XCode: return new XCodeProjectGenerator();
case ProjectFormat.Custom: case ProjectFormat.Custom:
if (CustomProjectTypes.TryGetValue(Configuration.ProjectFormatCustom, out var factory)) if (CustomProjectTypes.TryGetValue(Configuration.ProjectFormatCustom, out var factory))

View File

@@ -548,6 +548,10 @@ namespace Flax.Build.Projects.VisualStudioCode
json.AddField("**/*.flax", true); json.AddField("**/*.flax", true);
json.EndObject(); json.EndObject();
// Extension settings
json.AddField("omnisharp.useModernNet", false);
json.EndRootObject(); json.EndRootObject();
json.Save(Path.Combine(vsCodeFolder, "settings.json")); json.Save(Path.Combine(vsCodeFolder, "settings.json"));
} }