diff --git a/Source/Editor/Content/GUI/ContentView.cs b/Source/Editor/Content/GUI/ContentView.cs
index e0affeedc..bf9fb1715 100644
--- a/Source/Editor/Content/GUI/ContentView.cs
+++ b/Source/Editor/Content/GUI/ContentView.cs
@@ -536,15 +536,6 @@ namespace FlaxEditor.Content.GUI
}
}
- ///
- /// Called when user wants to rename item.
- ///
- /// The item.
- public void OnItemDoubleClickName(ContentItem item)
- {
- OnRename?.Invoke(item);
- }
-
///
/// Called when user wants to open item.
///
diff --git a/Source/Editor/Content/Items/ContentItem.cs b/Source/Editor/Content/Items/ContentItem.cs
index d887c304e..1cc6d480e 100644
--- a/Source/Editor/Content/Items/ContentItem.cs
+++ b/Source/Editor/Content/Items/ContentItem.cs
@@ -690,18 +690,9 @@ namespace FlaxEditor.Content
public override bool OnMouseDoubleClick(Float2 location, MouseButton button)
{
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
- (Parent as ContentView).OnItemDoubleClick(this);
- }
+
+ // Open
+ (Parent as ContentView).OnItemDoubleClick(this);
return true;
}
diff --git a/Source/Editor/Content/Tree/ContentTreeNode.cs b/Source/Editor/Content/Tree/ContentTreeNode.cs
index 2503cde51..1d70a8252 100644
--- a/Source/Editor/Content/Tree/ContentTreeNode.cs
+++ b/Source/Editor/Content/Tree/ContentTreeNode.cs
@@ -95,11 +95,19 @@ namespace FlaxEditor.Content
{
if (!_folder.CanRename)
return;
-
+ Editor.Instance.Windows.ContentWin.ScrollingOnTreeView(false);
// Start renaming the folder
var dialog = RenamePopup.Show(this, HeaderRect, _folder.ShortName, false);
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);
+ };
}
///
diff --git a/Source/Editor/CustomEditors/Dedicated/LayersMatrixEditor.cs b/Source/Editor/CustomEditors/Dedicated/LayersMatrixEditor.cs
index e6e2338d8..0f6996cc4 100644
--- a/Source/Editor/CustomEditors/Dedicated/LayersMatrixEditor.cs
+++ b/Source/Editor/CustomEditors/Dedicated/LayersMatrixEditor.cs
@@ -24,7 +24,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
public override void Initialize(LayoutElementsContainer layout)
{
string[] layerNames = LayersAndTagsSettings.GetCurrentLayers();
- int layersCount = Math.Max(4, layerNames.Length);
+ int layersCount = layerNames.Length;
_checkBoxes = new List();
_layersCount = layersCount;
diff --git a/Source/Editor/CustomEditors/Elements/FloatValueElement.cs b/Source/Editor/CustomEditors/Elements/FloatValueElement.cs
index ff2218a9b..6fc10e967 100644
--- a/Source/Editor/CustomEditors/Elements/FloatValueElement.cs
+++ b/Source/Editor/CustomEditors/Elements/FloatValueElement.cs
@@ -22,7 +22,7 @@ namespace FlaxEditor.CustomEditors.Elements
///
/// [Deprecated on 26.05.2022, expires on 26.05.2024]
///
- [System.Obsolete("Deprecated in 1.4")]
+ [System.Obsolete("Deprecated in 1.4, ValueBox instead")]
public FloatValueBox FloatValue => ValueBox;
///
diff --git a/Source/Editor/GUI/Input/ValueBox.cs b/Source/Editor/GUI/Input/ValueBox.cs
index ff824d76c..50cdd529c 100644
--- a/Source/Editor/GUI/Input/ValueBox.cs
+++ b/Source/Editor/GUI/Input/ValueBox.cs
@@ -56,6 +56,7 @@ namespace FlaxEditor.GUI.Input
private Float2 _startSlideLocation;
private double _clickStartTime = -1;
+ private bool _cursorChanged;
///
/// Occurs when value gets changed.
@@ -172,6 +173,11 @@ namespace FlaxEditor.GUI.Input
{
_isSliding = false;
EndMouseCapture();
+ if (_cursorChanged)
+ {
+ Cursor = CursorType.Default;
+ _cursorChanged = false;
+ }
SlidingEnd?.Invoke();
}
@@ -222,6 +228,8 @@ namespace FlaxEditor.GUI.Input
// Update
UpdateText();
}
+
+ Cursor = CursorType.Default;
ResetViewOffset();
}
@@ -236,6 +244,8 @@ namespace FlaxEditor.GUI.Input
_startSlideLocation = location;
_startSlideValue = _value;
StartMouseCapture(true);
+ Cursor = CursorType.SizeWE;
+ _cursorChanged = true;
SlidingStart?.Invoke();
return true;
}
@@ -249,13 +259,25 @@ namespace FlaxEditor.GUI.Input
///
public override void OnMouseMove(Float2 location)
{
- if (_isSliding)
+ if (_isSliding && !RootWindow.Window.IsMouseFlippingHorizontally)
{
// Update sliding
var slideLocation = location + Root.TrackingMouseOffset;
ApplySliding(Mathf.RoundToInt(slideLocation.X - _startSlideLocation.X) * _slideSpeed);
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);
}
@@ -281,6 +303,18 @@ namespace FlaxEditor.GUI.Input
return base.OnMouseUp(location, button);
}
+ ///
+ public override void OnMouseLeave()
+ {
+ if (_cursorChanged)
+ {
+ Cursor = CursorType.Default;
+ _cursorChanged = false;
+ }
+
+ base.OnMouseLeave();
+ }
+
///
protected override void OnEditBegin()
{
diff --git a/Source/Editor/GUI/Timeline/GUI/TimelineEdge.cs b/Source/Editor/GUI/Timeline/GUI/TimelineEdge.cs
index 0f1da6e9b..b74b47c46 100644
--- a/Source/Editor/GUI/Timeline/GUI/TimelineEdge.cs
+++ b/Source/Editor/GUI/Timeline/GUI/TimelineEdge.cs
@@ -69,10 +69,10 @@ namespace FlaxEditor.GUI.Timeline.GUI
///
public override void OnMouseMove(Float2 location)
{
- if (_isMoving)
+ if (_isMoving && !_timeline.RootWindow.Window.IsMouseFlippingHorizontally)
{
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 durationFrames = _timeline.DurationFrames;
@@ -83,6 +83,7 @@ namespace FlaxEditor.GUI.Timeline.GUI
else
{
_timeline.DurationFrames = _startMoveDuration + moveDelta;
+ _timeline.MediaBackground.HScrollBar.Value = _timeline.MediaBackground.HScrollBar.Maximum;
}
if (_timeline.DurationFrames != durationFrames)
@@ -140,6 +141,7 @@ namespace FlaxEditor.GUI.Timeline.GUI
_timeline.DurationFrames = duration;
}
_isMoving = false;
+ _timeline.MediaBackground.HScrollBar.Value = _timeline.MediaBackground.HScrollBar.Maximum;
EndMouseCapture();
}
diff --git a/Source/Editor/SceneGraph/GUI/ActorTreeNode.cs b/Source/Editor/SceneGraph/GUI/ActorTreeNode.cs
index 82e9c3c77..63043aa91 100644
--- a/Source/Editor/SceneGraph/GUI/ActorTreeNode.cs
+++ b/Source/Editor/SceneGraph/GUI/ActorTreeNode.cs
@@ -273,15 +273,26 @@ namespace FlaxEditor.SceneGraph.GUI
Select();
+ // Disable scrolling of scene view
+ Editor.Instance.Windows.SceneWin.ScrollingOnSceneTreeView(false);
+
// Start renaming the actor
var dialog = RenamePopup.Show(this, HeaderRect, _actorNode.Name, false);
dialog.Renamed += OnRenamed;
+ dialog.Closed += popup =>
+ {
+ // Enable scrolling of scene view
+ Editor.Instance.Windows.SceneWin.ScrollingOnSceneTreeView(true);
+ };
}
private void OnRenamed(RenamePopup renamePopup)
{
using (new UndoBlock(ActorNode.Root.Undo, Actor, "Rename"))
Actor.Name = renamePopup.Text;
+
+ // Enable scrolling of scene view
+ Editor.Instance.Windows.SceneWin.ScrollingOnSceneTreeView(true);
}
///
diff --git a/Source/Editor/Surface/VisjectSurface.Input.cs b/Source/Editor/Surface/VisjectSurface.Input.cs
index ddd4ae565..02fe835f2 100644
--- a/Source/Editor/Surface/VisjectSurface.Input.cs
+++ b/Source/Editor/Surface/VisjectSurface.Input.cs
@@ -290,9 +290,23 @@ namespace FlaxEditor.Surface
// Change scale (disable scaling during selecting nodes)
if (IsMouseOver && !_leftMouseDown && !IsPrimaryMenuOpened)
{
- var viewCenter = ViewCenterPosition;
- ViewScale += delta * 0.1f;
- ViewCenterPosition = viewCenter;
+ var nextViewScale = ViewScale + delta * 0.1f;
+
+ if (delta > 0 && !_rightMouseDown)
+ {
+ // Scale towards mouse when zooming in
+ var nextCenterPosition = ViewPosition + location / ViewScale;
+ ViewScale = nextViewScale;
+ ViewPosition = nextCenterPosition - (location / ViewScale);
+ }
+ else
+ {
+ // Scale while keeping center position when zooming out or when dragging view
+ var viewCenter = ViewCenterPosition;
+ ViewScale = nextViewScale;
+ ViewCenterPosition = viewCenter;
+ }
+
return true;
}
diff --git a/Source/Editor/Windows/Assets/SkeletonMaskWindow.cs b/Source/Editor/Windows/Assets/SkeletonMaskWindow.cs
index 3627ef70e..301ccf9b4 100644
--- a/Source/Editor/Windows/Assets/SkeletonMaskWindow.cs
+++ b/Source/Editor/Windows/Assets/SkeletonMaskWindow.cs
@@ -7,6 +7,7 @@ using FlaxEditor.CustomEditors;
using FlaxEditor.CustomEditors.Editors;
using FlaxEditor.CustomEditors.Elements;
using FlaxEditor.GUI;
+using FlaxEditor.GUI.Tree;
using FlaxEditor.Viewport.Cameras;
using FlaxEditor.Viewport.Previews;
using FlaxEngine;
@@ -166,8 +167,21 @@ namespace FlaxEditor.Windows.Assets
var proxy = (PropertiesProxy)Values[0];
int nodeIndex = (int)checkBox.Tag;
proxy.NodesMask[nodeIndex] = checkBox.Checked;
+ if (Input.GetKey(KeyboardKeys.Shift))
+ SetTreeChecked(checkBox.Parent as TreeNode, checkBox.Checked);
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;
+ }
+ }
}
}
diff --git a/Source/Editor/Windows/ContentWindow.cs b/Source/Editor/Windows/ContentWindow.cs
index 0f9eba0c0..90cd77d11 100644
--- a/Source/Editor/Windows/ContentWindow.cs
+++ b/Source/Editor/Windows/ContentWindow.cs
@@ -27,6 +27,8 @@ namespace FlaxEditor.Windows
private const string ProjectDataLastViewedFolder = "LastViewedFolder";
private bool _isWorkspaceDirty;
private SplitPanel _split;
+ private Panel _contentViewPanel;
+ private Panel _contentTreePanel;
private ContentView _view;
private readonly ToolStrip _toolStrip;
@@ -95,7 +97,7 @@ namespace FlaxEditor.Windows
};
// 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,
Offsets = new Margin(0, 0, _toolStrip.Bottom, 0),
@@ -120,11 +122,20 @@ namespace FlaxEditor.Windows
};
_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
_tree = new Tree(false)
{
- Y = headerPanel.Bottom,
- Parent = _split.Panel1,
+ Parent = _contentTreePanel,
};
_tree.SelectedChanged += OnTreeSelectionChanged;
headerPanel.Parent = _split.Panel1;
@@ -159,13 +170,23 @@ namespace FlaxEditor.Windows
_viewDropdown.Items.Add(((ContentItemSearchFilter)i).ToString());
_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
_view = new ContentView
{
AnchorPreset = AnchorPresets.HorizontalStretchTop,
- Offsets = new Margin(0, 0, contentItemsSearchPanel.Bottom + 4, 0),
+ Offsets = new Margin(0, 0, 0, 0),
IsScrollable = true,
- Parent = _split.Panel2,
+ Parent = _contentViewPanel,
};
_view.OnOpen += Open;
_view.OnNavigateBack += NavigateBackward;
@@ -271,6 +292,30 @@ namespace FlaxEditor.Windows
RefreshView(SelectedNode);
}
+ ///
+ /// Enables or disables vertical and horizontal scrolling on the content tree panel
+ ///
+ /// The state to set scrolling to
+ public void ScrollingOnTreeView(bool enabled)
+ {
+ if (_contentTreePanel.VScrollBar != null)
+ _contentTreePanel.VScrollBar.ThumbEnabled = enabled;
+ if (_contentTreePanel.HScrollBar != null)
+ _contentTreePanel.HScrollBar.ThumbEnabled = enabled;
+ }
+
+ ///
+ /// Enables or disables vertical and horizontal scrolling on the content view panel
+ ///
+ /// The state to set scrolling to
+ public void ScrollingOnContentView(bool enabled)
+ {
+ if (_contentViewPanel.VScrollBar != null)
+ _contentViewPanel.VScrollBar.ThumbEnabled = enabled;
+ if (_contentViewPanel.HScrollBar != null)
+ _contentViewPanel.HScrollBar.ThumbEnabled = enabled;
+ }
+
///
/// Shows popup dialog with UI to rename content item.
///
@@ -285,6 +330,7 @@ namespace FlaxEditor.Windows
_split.Panel2.VScrollBar.ThumbEnabled = false;
if (_split.Panel2.HScrollBar != null)
_split.Panel2.HScrollBar.ThumbEnabled = false;
+ ScrollingOnContentView(false);
// Show rename popup
var popup = RenamePopup.Show(item, item.TextRectangle, item.ShortName, true);
@@ -298,6 +344,7 @@ namespace FlaxEditor.Windows
_split.Panel2.VScrollBar.ThumbEnabled = true;
if (_split.Panel2.HScrollBar != null)
_split.Panel2.HScrollBar.ThumbEnabled = true;
+ ScrollingOnContentView(true);
// Check if was creating new element
if (_newElement != null)
diff --git a/Source/Editor/Windows/SceneTreeWindow.cs b/Source/Editor/Windows/SceneTreeWindow.cs
index bccba12c2..b0bed2002 100644
--- a/Source/Editor/Windows/SceneTreeWindow.cs
+++ b/Source/Editor/Windows/SceneTreeWindow.cs
@@ -131,6 +131,7 @@ namespace FlaxEditor.Windows
private TextBox _searchBox;
private Tree _tree;
+ private Panel _sceneTreePanel;
private bool _isUpdatingSelection;
private bool _isMouseDown;
@@ -143,10 +144,9 @@ namespace FlaxEditor.Windows
///
/// The editor.
public SceneTreeWindow(Editor editor)
- : base(editor, true, ScrollBars.Both)
+ : base(editor, true, ScrollBars.None)
{
Title = "Scene";
- ScrollMargin = new Margin(0, 0, 0, 100.0f);
// Scene searching query input box
var headerPanel = new ContainerControl
@@ -165,19 +165,29 @@ namespace FlaxEditor.Windows
};
_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
var root = editor.Scene.Root;
root.TreeNode.ChildrenIndent = 0;
root.TreeNode.Expand();
_tree = new Tree(true)
{
- Y = headerPanel.Bottom,
Margin = new Margin(0.0f, 0.0f, -16.0f, 0.0f), // Hide root node
+ IsScrollable = true,
};
_tree.AddChild(root.TreeNode);
_tree.SelectedChanged += Tree_OnSelectedChanged;
_tree.RightClick += OnTreeRightClick;
- _tree.Parent = this;
+ _tree.Parent = _sceneTreePanel;
headerPanel.Parent = this;
// Setup input actions
@@ -188,6 +198,18 @@ namespace FlaxEditor.Windows
InputActions.Add(options => options.Rename, Rename);
}
+ ///
+ /// Enables or disables vertical and horizontal scrolling on the scene tree panel.
+ ///
+ /// The state to set scrolling to
+ public void ScrollingOnSceneTreeView(bool enabled)
+ {
+ if (_sceneTreePanel.VScrollBar != null)
+ _sceneTreePanel.VScrollBar.ThumbEnabled = enabled;
+ if (_sceneTreePanel.HScrollBar != null)
+ _sceneTreePanel.HScrollBar.ThumbEnabled = enabled;
+ }
+
private void OnSearchBoxTextChanged()
{
// Skip events during setup or init stuff
diff --git a/Source/Engine/Core/Config/GraphicsSettings.h b/Source/Engine/Core/Config/GraphicsSettings.h
index c05698236..6a85a06b9 100644
--- a/Source/Engine/Core/Config/GraphicsSettings.h
+++ b/Source/Engine/Core/Config/GraphicsSettings.h
@@ -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.
///
API_FIELD(Attributes = "EditorOrder(1502), EditorDisplay(\"Quality\")")
- bool UeeHDRProbes = false;
+ bool UseHDRProbes = false;
///
/// 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)")
PostProcessSettings PostProcessSettings;
+private:
+ ///
+ /// Renamed UeeHDRProbes into UseHDRProbes
+ /// [Deprecated on 12.10.2022, expires on 12.10.2024]
+ ///
+ API_PROPERTY(Attributes="Serialize, Obsolete, NoUndo") bool GetUeeHDRProbes() const
+ {
+ return UseHDRProbes;
+ }
+
+ API_PROPERTY(Attributes="Serialize, Obsolete, NoUndo") void SetUeeHDRProbes(bool value)
+ {
+ UseHDRProbes = value;
+ }
+
public:
///
/// Gets the instance of the settings asset (default value if missing). Object returned by this method is always loaded with valid data to use.
diff --git a/Source/Engine/Level/Actors/Camera.cpp b/Source/Engine/Level/Actors/Camera.cpp
index a91074ab5..142baa745 100644
--- a/Source/Engine/Level/Actors/Camera.cpp
+++ b/Source/Engine/Level/Actors/Camera.cpp
@@ -120,6 +120,25 @@ void Camera::ProjectPoint(const Vector3& worldSpaceLocation, Float2& cameraViewp
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
{
return ConvertMouseToRay(mousePosition, GetViewport());
diff --git a/Source/Engine/Level/Actors/Camera.h b/Source/Engine/Level/Actors/Camera.h
index 2b59ab323..465130110 100644
--- a/Source/Engine/Level/Actors/Camera.h
+++ b/Source/Engine/Level/Actors/Camera.h
@@ -168,6 +168,13 @@ public:
/// The viewport.
API_FUNCTION() void ProjectPoint(const Vector3& worldSpaceLocation, API_PARAM(Out) Float2& cameraViewportSpaceLocation, API_PARAM(Ref) const Viewport& viewport) const;
+ ///
+ /// Checks if the 3d point of the world is in the camera's field of view.
+ ///
+ /// World Position (XYZ).
+ /// Returns true if the point is within the field of view.
+ API_FUNCTION() bool IsPointOnView(const Vector3& worldSpaceLocation) const;
+
///
/// Converts the mouse position to 3D ray.
///
diff --git a/Source/Engine/Platform/Base/WindowBase.h b/Source/Engine/Platform/Base/WindowBase.h
index 9782f40bb..ebeeb6b45 100644
--- a/Source/Engine/Platform/Base/WindowBase.h
+++ b/Source/Engine/Platform/Base/WindowBase.h
@@ -287,6 +287,8 @@ protected:
bool _isUsingMouseOffset;
Rectangle _mouseOffsetScreenSize;
bool _isTrackingMouse;
+ bool _isHorizontalFlippingMouse;
+ bool _isVerticalFlippingMouse;
bool _isClippingCursor;
explicit WindowBase(const CreateWindowSettings& settings);
@@ -680,6 +682,22 @@ public:
return _isTrackingMouse;
}
+ ///
+ /// Gets the value indicating if the mouse flipped to the other screen edge horizontally
+ ///
+ API_PROPERTY() bool IsMouseFlippingHorizontally() const
+ {
+ return _isHorizontalFlippingMouse;
+ }
+
+ ///
+ /// Gets the value indicating if the mouse flipped to the other screen edge vertically
+ ///
+ API_PROPERTY() bool IsMouseFlippingVertically() const
+ {
+ return _isVerticalFlippingMouse;
+ }
+
///
/// Ends the mouse tracking.
///
diff --git a/Source/Engine/Platform/SettingsBase.cs b/Source/Engine/Platform/SettingsBase.cs
index 505195819..ab25592a5 100644
--- a/Source/Engine/Platform/SettingsBase.cs
+++ b/Source/Engine/Platform/SettingsBase.cs
@@ -1,5 +1,8 @@
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
+using System;
+using FlaxEngine;
+
namespace FlaxEditor.Content.Settings
{
///
@@ -11,13 +14,24 @@ namespace FlaxEditor.Content.Settings
partial class GraphicsSettings
{
+ ///
+ /// Renamed UeeHDRProbes into UseHDRProbes
+ /// [Deprecated on 12.10.2022, expires on 12.10.2024]
+ ///
+ [Serialize, Obsolete, NoUndo]
+ private bool UeeHDRProbes
+ {
+ get => UseHDRProbes;
+ set => UseHDRProbes = value;
+ }
+
///
/// Initializes a new instance of the .
///
public GraphicsSettings()
{
// Initialize PostFx settings with default options (C# structs don't support it)
- PostProcessSettings = FlaxEngine.PostProcessSettings.Default;
+ PostProcessSettings = PostProcessSettings.Default;
}
}
}
diff --git a/Source/Engine/Platform/Windows/WindowsWindow.cpp b/Source/Engine/Platform/Windows/WindowsWindow.cpp
index 0cd6aab95..da7692eeb 100644
--- a/Source/Engine/Platform/Windows/WindowsWindow.cpp
+++ b/Source/Engine/Platform/Windows/WindowsWindow.cpp
@@ -544,6 +544,8 @@ void WindowsWindow::StartTrackingMouse(bool useMouseScreenOffset)
_isTrackingMouse = true;
_trackingMouseOffset = Float2::Zero;
_isUsingMouseOffset = useMouseScreenOffset;
+ _isHorizontalFlippingMouse = false;
+ _isVerticalFlippingMouse = false;
int32 x = 0, y = 0, width = 0, height = 0;
GetScreenInfo(x, y, width, height);
@@ -558,6 +560,8 @@ void WindowsWindow::EndTrackingMouse()
if (_isTrackingMouse)
{
_isTrackingMouse = false;
+ _isHorizontalFlippingMouse = false;
+ _isVerticalFlippingMouse = false;
ReleaseCapture();
}
@@ -824,14 +828,14 @@ LRESULT WindowsWindow::WndProc(UINT msg, WPARAM wParam, LPARAM lParam)
const Float2 mousePos(static_cast(WINDOWS_GET_X_LPARAM(lParam)), static_cast(WINDOWS_GET_Y_LPARAM(lParam)));
Float2 mousePosition = ClientToScreen(mousePos);
Float2 newMousePosition = mousePosition;
- if (mousePosition.X <= desktopLocation.X + 2)
- newMousePosition.X = desktopSize.X - 2;
- else if (mousePosition.X >= desktopSize.X - 1)
- newMousePosition.X = desktopLocation.X + 2;
- if (mousePosition.Y <= desktopLocation.Y + 2)
- newMousePosition.Y = desktopSize.Y - 2;
- else if (mousePosition.Y >= desktopSize.Y - 1)
- newMousePosition.Y = desktopLocation.Y + 2;
+ if (_isHorizontalFlippingMouse = mousePosition.X <= desktopLocation.X + 2)
+ newMousePosition.X = desktopSize.X - 3;
+ else if (_isHorizontalFlippingMouse = mousePosition.X >= desktopSize.X - 1)
+ newMousePosition.X = desktopLocation.X + 3;
+ if (_isVerticalFlippingMouse = mousePosition.Y <= desktopLocation.Y + 2)
+ newMousePosition.Y = desktopSize.Y - 3;
+ else if (_isVerticalFlippingMouse = mousePosition.Y >= desktopSize.Y - 1)
+ newMousePosition.Y = desktopLocation.Y + 3;
if (!Float2::NearEqual(mousePosition, newMousePosition))
{
_trackingMouseOffset -= newMousePosition - mousePosition;
diff --git a/Source/Engine/Renderer/ProbesRenderer.cpp b/Source/Engine/Renderer/ProbesRenderer.cpp
index 51791edd3..c1c273de8 100644
--- a/Source/Engine/Renderer/ProbesRenderer.cpp
+++ b/Source/Engine/Renderer/ProbesRenderer.cpp
@@ -204,7 +204,7 @@ int32 ProbesRenderer::Entry::GetResolution() 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()
diff --git a/Source/Engine/UI/GUI/Control.cs b/Source/Engine/UI/GUI/Control.cs
index 8384741bc..86c242609 100644
--- a/Source/Engine/UI/GUI/Control.cs
+++ b/Source/Engine/UI/GUI/Control.cs
@@ -948,6 +948,10 @@ namespace FlaxEngine.GUI
{
// Set flag
_isDragOver = true;
+
+ // Hide tooltip
+ Tooltip?.Hide();
+
return DragDropEffect.None;
}
diff --git a/Source/Engine/UI/GUI/Panels/SplitPanel.cs b/Source/Engine/UI/GUI/Panels/SplitPanel.cs
index 8772c78e6..2a46846e8 100644
--- a/Source/Engine/UI/GUI/Panels/SplitPanel.cs
+++ b/Source/Engine/UI/GUI/Panels/SplitPanel.cs
@@ -23,6 +23,7 @@ namespace FlaxEngine.GUI
private float _splitterValue;
private Rectangle _splitterRect;
private bool _splitterClicked, _mouseOverSplitter;
+ private bool _cursorChanged;
///
/// The first panel (left or upper based on Orientation).
@@ -161,6 +162,18 @@ namespace FlaxEngine.GUI
if (_splitterClicked)
{
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);
@@ -197,6 +210,11 @@ namespace FlaxEngine.GUI
{
// Clear flag
_mouseOverSplitter = false;
+ if (_cursorChanged)
+ {
+ Cursor = CursorType.Default;
+ _cursorChanged = false;
+ }
base.OnMouseLeave();
}
diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs
index 549e55d2d..53165cac3 100644
--- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs
+++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs
@@ -922,10 +922,8 @@ namespace Flax.Build.Bindings
// Properties
foreach (var propertyInfo in classInfo.Properties)
{
- if (propertyInfo.IsHidden)
+ if (propertyInfo.IsHidden || !useUnmanaged)
continue;
- if (!useUnmanaged)
- throw new NotImplementedException("TODO: support properties inside non-static and non-scripting API class types.");
contents.AppendLine();
GenerateCSharpComment(contents, indent, propertyInfo.Comment, true);
diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs
index 1f6fcfb04..f178af64b 100644
--- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs
+++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs
@@ -1446,6 +1446,11 @@ namespace Flax.Build.Bindings
continue;
if (GenerateCppAutoSerializationSkip(buildData, typeInfo, propertyInfo, propertyInfo.Type))
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(" const auto");
@@ -1462,7 +1467,6 @@ namespace Flax.Build.Bindings
contents.Append($"stream.JKEY(\"{propertyInfo.Name}\"); Serialization::Serialize(stream, value, nullptr);");
contents.Append(" }");
contents.Append('}').AppendLine();
- CppAutoSerializeProperties.Add(propertyInfo);
}
}
else if (structureInfo != null)
@@ -1494,14 +1498,14 @@ namespace Flax.Build.Bindings
foreach (var propertyInfo in CppAutoSerializeProperties)
{
- contents.Append(" {");
- contents.Append($" const auto e = SERIALIZE_FIND_MEMBER(stream, \"{propertyInfo.Name}\");");
- contents.Append(" if (e != stream.MemberEnd()) {");
- contents.Append($" auto p = {propertyInfo.Getter.Name}();");
- contents.Append(" Serialization::Deserialize(e->value, p, modifier);");
- contents.Append($" {propertyInfo.Setter.Name}(p);");
- contents.Append(" }");
- contents.Append('}').AppendLine();
+ contents.AppendLine(" {");
+ contents.AppendLine($" const auto e = SERIALIZE_FIND_MEMBER(stream, \"{propertyInfo.Name}\");");
+ contents.AppendLine(" if (e != stream.MemberEnd()) {");
+ contents.AppendLine($" auto p = {propertyInfo.Getter.Name}();");
+ contents.AppendLine(" Serialization::Deserialize(e->value, p, modifier);");
+ contents.AppendLine($" {propertyInfo.Setter.Name}(p);");
+ contents.AppendLine(" }");
+ contents.AppendLine(" }");
}
contents.Append('}').AppendLine();
diff --git a/Source/Tools/Flax.Build/Build/Builder.Projects.cs b/Source/Tools/Flax.Build/Build/Builder.Projects.cs
index bb645a940..1772cb444 100644
--- a/Source/Tools/Flax.Build/Build/Builder.Projects.cs
+++ b/Source/Tools/Flax.Build/Build/Builder.Projects.cs
@@ -435,7 +435,7 @@ namespace Flax.Build
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)
- 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"));
}
}
}
diff --git a/Source/Tools/Flax.Build/Build/Platform.cs b/Source/Tools/Flax.Build/Build/Platform.cs
index 72e6454a4..99edc7889 100644
--- a/Source/Tools/Flax.Build/Build/Platform.cs
+++ b/Source/Tools/Flax.Build/Build/Platform.cs
@@ -245,6 +245,24 @@ namespace Flax.Build
return toolchain;
}
+ ///
+ /// Gets path to the current platform binary directory
+ ///
+ 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();
+ }
+
///
/// Creates the project files generator for the specified project format.
///
diff --git a/Source/Tools/Flax.Build/Configuration.cs b/Source/Tools/Flax.Build/Configuration.cs
index 55f3d138d..4c3f63b0c 100644
--- a/Source/Tools/Flax.Build/Configuration.cs
+++ b/Source/Tools/Flax.Build/Configuration.cs
@@ -39,6 +39,12 @@ namespace Flax.Build
[CommandLine("deploy", "Runs the deploy tool.")]
public static bool Deploy = false;
+ ///
+ /// Compresses deployed files.
+ ///
+ [CommandLine("deployDontCompress", "Skips compressing deployed files, and keeps files.")]
+ public static bool DontCompress = false;
+
///
/// Builds the targets. Builds all the targets, use to select a custom set of targets for the build.
///
diff --git a/Source/Tools/Flax.Build/Deploy/Deployment.Editor.cs b/Source/Tools/Flax.Build/Deploy/Deployment.Editor.cs
index ad94da918..c4ca880f7 100644
--- a/Source/Tools/Flax.Build/Deploy/Deployment.Editor.cs
+++ b/Source/Tools/Flax.Build/Deploy/Deployment.Editor.cs
@@ -7,6 +7,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using Flax.Build;
+using Flax.Build.Platforms;
namespace Flax.Deploy
{
@@ -126,21 +127,24 @@ namespace Flax.Deploy
DeployFile(RootPath, OutputPath, "Flax.flaxproj");
// Compress
+ if (Configuration.DontCompress)
+ return;
+
Log.Info(string.Empty);
Log.Info("Compressing editor files...");
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)
- editorPackageZipPath = Path.Combine(Deployer.PackageOutputPath, "FlaxEditorLinux.zip");
- Utilities.FileDelete(editorPackageZipPath);
- Utilities.Run("zip", "Editor.zip -r .", null, OutputPath, Utilities.RunOptions.ThrowExceptionOnError);
- File.Move(Path.Combine(OutputPath, "Editor.zip"), editorPackageZipPath);
+ var zipEofPath = UnixPlatform.Which("zip");
+ unix = File.Exists(zipEofPath);
+ if (!unix)
+ Log.Verbose("Using .NET compressing");
}
- else if (Platform.BuildTargetPlatform == TargetPlatform.Mac)
+ if (unix)
{
// 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.Run("zip", "Editor.zip -r .", null, OutputPath, Utilities.RunOptions.ThrowExceptionOnError);
File.Move(Path.Combine(OutputPath, "Editor.zip"), editorPackageZipPath);
@@ -189,13 +193,14 @@ namespace Flax.Deploy
private static void DeployEditorBinaries(TargetConfiguration configuration)
{
+ var binariesSubDir = Path.Combine(Platform.GetEditorBinaryDirectory(), configuration.ToString());
+ var src = Path.Combine(RootPath, binariesSubDir);
+ var dst = Path.Combine(OutputPath, binariesSubDir);
+ Directory.CreateDirectory(dst);
+
if (Platform.BuildTargetPlatform == TargetPlatform.Windows)
{
- var binariesSubDir = "Binaries/Editor/Win64/" + configuration;
- var src = Path.Combine(RootPath, binariesSubDir);
- var dst = Path.Combine(OutputPath, binariesSubDir);
var dstDebug = Path.Combine(Deployer.PackageOutputPath, "EditorDebugSymbols/Win64/" + configuration);
- Directory.CreateDirectory(dst);
Directory.CreateDirectory(dstDebug);
// Validate that build editor app has a valid version number
@@ -229,11 +234,6 @@ namespace Flax.Deploy
}
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
DeployFile(src, dst, "FlaxEditor");
DeployFile(src, dst, "FlaxEditor.Build.json");
@@ -253,11 +253,6 @@ namespace Flax.Deploy
}
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
DeployFile(src, dst, "FlaxEditor");
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", "libMoltenVK.dylib", null, dst, Utilities.RunOptions.None);
}
- else
- {
- throw new NotImplementedException();
- }
}
}
}
diff --git a/Source/Tools/Flax.Build/Deploy/Deployment.Platforms.cs b/Source/Tools/Flax.Build/Deploy/Deployment.Platforms.cs
index 78e6183bb..9a6d372d2 100644
--- a/Source/Tools/Flax.Build/Deploy/Deployment.Platforms.cs
+++ b/Source/Tools/Flax.Build/Deploy/Deployment.Platforms.cs
@@ -63,6 +63,7 @@ namespace Flax.Deploy
}
// Compress
+ if (!Configuration.DontCompress)
{
Log.Info("Compressing platform files...");
@@ -84,10 +85,10 @@ namespace Flax.Deploy
#endif
Log.Info(string.Format("Compressed {0} package size: {1}", platformName, Utilities.GetFileSize(packageZipPath)));
- }
- // Remove files (only zip package is used)
- Utilities.DirectoryDelete(dst);
+ // Remove files (only zip package is used)
+ Utilities.DirectoryDelete(dst);
+ }
Log.Info(string.Empty);
}
diff --git a/Source/Tools/Flax.Build/Platforms/Linux/LinuxPlatform.cs b/Source/Tools/Flax.Build/Platforms/Linux/LinuxPlatform.cs
index 1d0433f50..ced516a54 100644
--- a/Source/Tools/Flax.Build/Platforms/Linux/LinuxPlatform.cs
+++ b/Source/Tools/Flax.Build/Platforms/Linux/LinuxPlatform.cs
@@ -58,7 +58,7 @@ namespace Flax.Build.Platforms
if (Compiler != null)
{
// System compiler
- ToolchainRoot = string.Empty;
+ ToolchainRoot = "/";
Log.Verbose($"Using native Linux toolchain (compiler {Compiler})");
HasRequiredSDKsInstalled = true;
}
diff --git a/Source/Tools/Flax.Build/Platforms/Linux/LinuxToolchain.cs b/Source/Tools/Flax.Build/Platforms/Linux/LinuxToolchain.cs
index ede17b639..2904b89a7 100644
--- a/Source/Tools/Flax.Build/Platforms/Linux/LinuxToolchain.cs
+++ b/Source/Tools/Flax.Build/Platforms/Linux/LinuxToolchain.cs
@@ -23,9 +23,16 @@ namespace Flax.Build.Platforms
: base(platform, architecture, platform.ToolchainRoot, platform.Compiler)
{
// Setup system paths
- SystemIncludePaths.Add(Path.Combine(ToolsetRoot, "usr", "include"));
- SystemIncludePaths.Add(Path.Combine(ToolsetRoot, "include", "c++", "5.2.0"));
- SystemIncludePaths.Add(Path.Combine(ToolsetRoot, "lib", "clang", ClangVersion.Major.ToString(), "include"));
+ var includePath = Path.Combine(ToolsetRoot, "usr", "include");
+ SystemIncludePaths.Add(includePath);
+ 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);
}
///
diff --git a/Source/Tools/Flax.Build/Projects/ProjectGenerator.cs b/Source/Tools/Flax.Build/Projects/ProjectGenerator.cs
index f218a9a4f..cb0e5311e 100644
--- a/Source/Tools/Flax.Build/Projects/ProjectGenerator.cs
+++ b/Source/Tools/Flax.Build/Projects/ProjectGenerator.cs
@@ -138,7 +138,9 @@ namespace Flax.Build.Projects
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.Custom:
if (CustomProjectTypes.TryGetValue(Configuration.ProjectFormatCustom, out var factory))
diff --git a/Source/Tools/Flax.Build/Projects/VisualStudioCode/VisualStudioCodeProjectGenerator.cs b/Source/Tools/Flax.Build/Projects/VisualStudioCode/VisualStudioCodeProjectGenerator.cs
index e925e70ae..872354f22 100644
--- a/Source/Tools/Flax.Build/Projects/VisualStudioCode/VisualStudioCodeProjectGenerator.cs
+++ b/Source/Tools/Flax.Build/Projects/VisualStudioCode/VisualStudioCodeProjectGenerator.cs
@@ -547,6 +547,10 @@ namespace Flax.Build.Projects.VisualStudioCode
json.AddField("**/Output", true);
json.AddField("**/*.flax", true);
json.EndObject();
+
+ // Extension settings
+ json.AddField("omnisharp.useModernNet", false);
+
json.EndRootObject();
json.Save(Path.Combine(vsCodeFolder, "settings.json"));