From 7c4b8758eabefe7794ea99bc06c18a4e52a1dec0 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Wed, 22 May 2024 21:10:01 -0500 Subject: [PATCH 01/11] Fix a few edge cases for cursor showing/not showing --- Source/Engine/Platform/Windows/WindowsWindow.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Engine/Platform/Windows/WindowsWindow.cpp b/Source/Engine/Platform/Windows/WindowsWindow.cpp index f259ce337..1f53abe75 100644 --- a/Source/Engine/Platform/Windows/WindowsWindow.cpp +++ b/Source/Engine/Platform/Windows/WindowsWindow.cpp @@ -778,7 +778,7 @@ void WindowsWindow::UpdateCursor() if (!_lastCursorHidden) { _lastCursorHidden = true; - ::ShowCursor(FALSE); + while(::ShowCursor(FALSE) >= 0); } ::SetCursor(nullptr); return; @@ -786,7 +786,7 @@ void WindowsWindow::UpdateCursor() else if (_lastCursorHidden) { _lastCursorHidden = false; - ::ShowCursor(TRUE); + while(::ShowCursor(TRUE) < 0); } int32 index = 0; From f01784108dc738464b2bd7ae0f75c246c0005c78 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Thu, 30 May 2024 08:47:41 -0500 Subject: [PATCH 02/11] Add check to cursor hidden/showing loops. --- .../Engine/Platform/Windows/WindowsWindow.cpp | 22 +++++++++++++++++-- .../Engine/Platform/Windows/WindowsWindow.h | 1 + 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/Source/Engine/Platform/Windows/WindowsWindow.cpp b/Source/Engine/Platform/Windows/WindowsWindow.cpp index 1f53abe75..78cea0a3c 100644 --- a/Source/Engine/Platform/Windows/WindowsWindow.cpp +++ b/Source/Engine/Platform/Windows/WindowsWindow.cpp @@ -778,7 +778,16 @@ void WindowsWindow::UpdateCursor() if (!_lastCursorHidden) { _lastCursorHidden = true; - while(::ShowCursor(FALSE) >= 0); + while(::ShowCursor(FALSE) >= 0) + { + if (_cursorHiddenSafetyCount >= 100) + { + LOG(Warning, "Cursor has failed to hide."); + break; + } + _cursorHiddenSafetyCount += 1; + } + _cursorHiddenSafetyCount = 0; } ::SetCursor(nullptr); return; @@ -786,7 +795,16 @@ void WindowsWindow::UpdateCursor() else if (_lastCursorHidden) { _lastCursorHidden = false; - while(::ShowCursor(TRUE) < 0); + while(::ShowCursor(TRUE) < 0) + { + if (_cursorHiddenSafetyCount >= 100) + { + LOG(Warning, "Cursor has failed to show."); + break; + } + _cursorHiddenSafetyCount += 1; + } + _cursorHiddenSafetyCount = 0; } int32 index = 0; diff --git a/Source/Engine/Platform/Windows/WindowsWindow.h b/Source/Engine/Platform/Windows/WindowsWindow.h index c2dad4a13..6c720ba07 100644 --- a/Source/Engine/Platform/Windows/WindowsWindow.h +++ b/Source/Engine/Platform/Windows/WindowsWindow.h @@ -29,6 +29,7 @@ private: bool _trackingMouse = false; bool _clipCursorSet = false; bool _lastCursorHidden = false; + int _cursorHiddenSafetyCount = 0; bool _isDuringMaximize = false; Windows::HANDLE _monitor = nullptr; Windows::LONG _clipCursorRect[4]; From 0c50fa98161061e18aaadf3a5d7b8d457a525d06 Mon Sep 17 00:00:00 2001 From: Nils Hausfeld Date: Fri, 31 May 2024 20:16:33 +0200 Subject: [PATCH 03/11] - Implemented a connection line offset that increases the less curvature the line has - Made connection lines a tiny bit thicker and added constants at the top of OutputBox to easily change the default style --- Source/Editor/Surface/Archetypes/Tools.cs | 2 +- Source/Editor/Surface/Elements/Box.cs | 2 +- Source/Editor/Surface/Elements/OutputBox.cs | 71 ++++++++++++++++----- 3 files changed, 57 insertions(+), 18 deletions(-) diff --git a/Source/Editor/Surface/Archetypes/Tools.cs b/Source/Editor/Surface/Archetypes/Tools.cs index ee2bf4718..e2b330616 100644 --- a/Source/Editor/Surface/Archetypes/Tools.cs +++ b/Source/Editor/Surface/Archetypes/Tools.cs @@ -1266,7 +1266,7 @@ namespace FlaxEditor.Surface.Archetypes /// public void DrawConnectingLine(ref Float2 startPos, ref Float2 endPos, ref Color color) { - OutputBox.DrawConnection(Surface.Style, ref startPos, ref endPos, ref color, 2); + OutputBox.DrawConnection(Surface.Style, ref startPos, ref endPos, ref color, OutputBox.ConnectingConnectionThickness); } /// diff --git a/Source/Editor/Surface/Elements/Box.cs b/Source/Editor/Surface/Elements/Box.cs index eca1e15af..6f7438579 100644 --- a/Source/Editor/Surface/Elements/Box.cs +++ b/Source/Editor/Surface/Elements/Box.cs @@ -738,7 +738,7 @@ namespace FlaxEditor.Surface.Elements /// public void DrawConnectingLine(ref Float2 startPos, ref Float2 endPos, ref Color color) { - OutputBox.DrawConnection(Surface.Style, ref startPos, ref endPos, ref color, 2); + OutputBox.DrawConnection(Surface.Style, ref startPos, ref endPos, ref color, OutputBox.ConnectingConnectionThickness); } /// diff --git a/Source/Editor/Surface/Elements/OutputBox.cs b/Source/Editor/Surface/Elements/OutputBox.cs index d60e283f4..558d9d7e4 100644 --- a/Source/Editor/Surface/Elements/OutputBox.cs +++ b/Source/Editor/Surface/Elements/OutputBox.cs @@ -14,6 +14,26 @@ namespace FlaxEditor.Surface.Elements [HideInEditor] public class OutputBox : Box { + /// + /// The default thickness of the connection line + /// + public const float DefaultConnectionThickness = 1.5f; + + /// + /// The thickness of a highlighted connection line + /// + public const float ConnectingConnectionThickness = 2.5f; + + /// + /// The thickness of the selected connection line + /// + public const float SelectedConnectionThickness = 3f; + + /// + /// The offset between the connection line and the box + /// + public const float DefaultConnectionOffset = 24f; + /// /// Distance for the mouse to be considered above the connection /// @@ -33,7 +53,7 @@ namespace FlaxEditor.Surface.Elements /// The end location. /// The connection color. /// The connection thickness. - public static void DrawConnection(SurfaceStyle style, ref Float2 start, ref Float2 end, ref Color color, float thickness = 1) + public static void DrawConnection(SurfaceStyle style, ref Float2 start, ref Float2 end, ref Color color, float thickness = DefaultConnectionThickness) { if (style.DrawConnection != null) { @@ -41,11 +61,22 @@ namespace FlaxEditor.Surface.Elements return; } + float connectionOffset = Mathf.Max(0f, DefaultConnectionOffset * (1 - Editor.Instance.Options.Options.Interface.ConnectionCurvature)); + Float2 offsetStart = new Float2(start.X + connectionOffset, start.Y); + Float2 offsetEnd = new Float2(end.X - connectionOffset, end.Y); + // Calculate control points - CalculateBezierControlPoints(start, end, out var control1, out var control2); + CalculateBezierControlPoints(offsetStart, offsetEnd, out var control1, out var control2); + + // Draw offset lines only if necessary + if (connectionOffset >= float.Epsilon) + { + Render2D.DrawLine(start, offsetStart, color, thickness); + Render2D.DrawLine(offsetEnd, end, color, thickness); + } // Draw line - Render2D.DrawBezier(start, control1, control2, end, color, thickness); + Render2D.DrawBezier(offsetStart, control1, control2, offsetEnd, color, thickness); /* // Debug drawing control points @@ -80,9 +111,10 @@ namespace FlaxEditor.Surface.Elements /// The mouse position public bool IntersectsConnection(Box targetBox, ref Float2 mousePosition) { - var startPos = ConnectionOrigin; - var endPos = targetBox.ConnectionOrigin; - return IntersectsConnection(ref startPos, ref endPos, ref mousePosition, MouseOverConnectionDistance); + float connectionOffset = Mathf.Max(0f, DefaultConnectionOffset * (1 - Editor.Instance.Options.Options.Interface.ConnectionCurvature)); + Float2 start = new Float2(ConnectionOrigin.X + connectionOffset, ConnectionOrigin.Y); + Float2 end = new Float2(targetBox.ConnectionOrigin.X - connectionOffset, targetBox.ConnectionOrigin.Y); + return IntersectsConnection(ref start, ref end, ref mousePosition, MouseOverConnectionDistance); } /// @@ -102,22 +134,26 @@ namespace FlaxEditor.Surface.Elements if ((point.Y - (start.Y - offset)) * ((end.Y + offset) - point.Y) < 0) return false; - float squaredDistance = distance; - CalculateBezierControlPoints(start, end, out var control1, out var control2); + float connectionOffset = Mathf.Max(0f, DefaultConnectionOffset * (1 - Editor.Instance.Options.Options.Interface.ConnectionCurvature)); + Float2 offsetStart = new Float2(start.X + connectionOffset, start.Y); + Float2 offsetEnd = new Float2(end.X - connectionOffset, end.Y); - var d1 = control1 - start; + float squaredDistance = distance; + CalculateBezierControlPoints(offsetStart, offsetEnd, out var control1, out var control2); + + var d1 = control1 - offsetStart; var d2 = control2 - control1; - var d3 = end - control2; + var d3 = offsetEnd - control2; float len = d1.Length + d2.Length + d3.Length; int segmentCount = Math.Min(Math.Max(Mathf.CeilToInt(len * 0.05f), 1), 100); float segmentCountInv = 1.0f / segmentCount; - Bezier(ref start, ref control1, ref control2, ref end, 0, out var p); + Bezier(ref offsetStart, ref control1, ref control2, ref offsetEnd, 0, out var p); for (int i = 1; i <= segmentCount; i++) { var oldp = p; float t = i * segmentCountInv; - Bezier(ref start, ref control1, ref control2, ref end, t, out p); + Bezier(ref offsetStart, ref control1, ref control2, ref offsetEnd, t, out p); // Maybe it would be reasonable to return the point? CollisionsHelper.ClosestPointPointLine(ref point, ref oldp, ref p, out var result); @@ -153,14 +189,17 @@ namespace FlaxEditor.Surface.Elements { Box targetBox = Connections[i]; var endPos = targetBox.ConnectionOrigin; - var highlight = 1 + Mathf.Max(startHighlight, targetBox.ConnectionsHighlightIntensity); + var highlight = DefaultConnectionThickness + Mathf.Max(startHighlight, targetBox.ConnectionsHighlightIntensity); var alpha = targetBox.Enabled && targetBox.IsActive ? 1.0f : 0.6f; - var color = _currentTypeColor * highlight * alpha; + + // We have to calculate an offset here to preserve the original color for when the default connection thickness is larger than 1 + var highlightOffset = (highlight - (DefaultConnectionThickness - 1)); + var color = _currentTypeColor * highlightOffset * alpha; // TODO: Figure out how to only draw the topmost connection if (IntersectsConnection(ref startPos, ref endPos, ref mousePosition, mouseOverDistance)) { - highlight += 0.5f; + highlight += DefaultConnectionThickness * 0.5f; } DrawConnection(style, ref startPos, ref endPos, ref color, highlight); @@ -177,7 +216,7 @@ namespace FlaxEditor.Surface.Elements var endPos = targetBox.ConnectionOrigin; var alpha = targetBox.Enabled && targetBox.IsActive ? 1.0f : 0.6f; var color = _currentTypeColor * alpha; - DrawConnection(Surface.Style, ref startPos, ref endPos, ref color, 2.5f); + DrawConnection(Surface.Style, ref startPos, ref endPos, ref color, SelectedConnectionThickness); } /// From 9e9013ec432a853320827e595b6ec00491410284 Mon Sep 17 00:00:00 2001 From: ExMatics HydrogenC <33123710+HydrogenC@users.noreply.github.com> Date: Sat, 1 Jun 2024 18:23:37 +0800 Subject: [PATCH 04/11] Add missing recalculations of the thumb --- Source/Engine/UI/GUI/Panels/ScrollBar.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Source/Engine/UI/GUI/Panels/ScrollBar.cs b/Source/Engine/UI/GUI/Panels/ScrollBar.cs index bb45accf7..712c3e606 100644 --- a/Source/Engine/UI/GUI/Panels/ScrollBar.cs +++ b/Source/Engine/UI/GUI/Panels/ScrollBar.cs @@ -100,6 +100,7 @@ namespace FlaxEngine.GUI if (value > _maximum) throw new ArgumentOutOfRangeException(); _minimum = value; + UpdateThumb(); if (Value < _minimum) Value = _minimum; } @@ -116,6 +117,7 @@ namespace FlaxEngine.GUI if (value < _minimum) throw new ArgumentOutOfRangeException(); _maximum = value; + UpdateThumb(); if (Value > _maximum) Value = _maximum; } From dedb3d57fd2d996e31440a3c2245b84313f145d0 Mon Sep 17 00:00:00 2001 From: Ari Vuollet Date: Sat, 1 Jun 2024 20:22:16 +0300 Subject: [PATCH 05/11] Fix Variant getters returning already freed managed handles --- Source/Engine/AI/BehaviorKnowledge.cpp | 2 +- Source/Engine/AI/BehaviorKnowledge.h | 2 +- Source/Engine/Engine/GameplayGlobals.cpp | 2 +- Source/Engine/Engine/GameplayGlobals.h | 2 +- Source/Engine/Level/Actors/AnimatedModel.cpp | 4 ++-- Source/Engine/Level/Actors/AnimatedModel.h | 4 ++-- Source/Engine/Particles/ParticleEffect.cpp | 6 +++--- Source/Engine/Particles/ParticleEffect.h | 6 +++--- 8 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Source/Engine/AI/BehaviorKnowledge.cpp b/Source/Engine/AI/BehaviorKnowledge.cpp index a6593dd07..5bca8c627 100644 --- a/Source/Engine/AI/BehaviorKnowledge.cpp +++ b/Source/Engine/AI/BehaviorKnowledge.cpp @@ -212,7 +212,7 @@ bool BehaviorKnowledge::HasGoal(ScriptingTypeHandle type) const return false; } -Variant BehaviorKnowledge::GetGoal(ScriptingTypeHandle type) +const Variant& BehaviorKnowledge::GetGoal(ScriptingTypeHandle type) const { for (const Variant& goal : Goals) { diff --git a/Source/Engine/AI/BehaviorKnowledge.h b/Source/Engine/AI/BehaviorKnowledge.h index 8a92a9fa7..aef894c73 100644 --- a/Source/Engine/AI/BehaviorKnowledge.h +++ b/Source/Engine/AI/BehaviorKnowledge.h @@ -101,7 +101,7 @@ public: /// /// The goal type. /// The goal value or null if not found. - API_FUNCTION() Variant GetGoal(ScriptingTypeHandle type); + API_FUNCTION() const Variant& GetGoal(ScriptingTypeHandle type) const; /// /// Adds the goal to the knowledge. If goal of that type already exists then it's value is updated. diff --git a/Source/Engine/Engine/GameplayGlobals.cpp b/Source/Engine/Engine/GameplayGlobals.cpp index eba975e2b..eedd30d3a 100644 --- a/Source/Engine/Engine/GameplayGlobals.cpp +++ b/Source/Engine/Engine/GameplayGlobals.cpp @@ -124,7 +124,7 @@ void GameplayGlobals::SetDefaultValues(const Dictionary& values } } -Variant GameplayGlobals::GetValue(const StringView& name) const +const Variant& GameplayGlobals::GetValue(const StringView& name) const { ScopeLock lock(Locker); auto e = Variables.TryGet(name); diff --git a/Source/Engine/Engine/GameplayGlobals.h b/Source/Engine/Engine/GameplayGlobals.h index 7f9e50275..4f09ba4c8 100644 --- a/Source/Engine/Engine/GameplayGlobals.h +++ b/Source/Engine/Engine/GameplayGlobals.h @@ -66,7 +66,7 @@ public: /// /// The variable name. /// The value. - API_FUNCTION() Variant GetValue(const StringView& name) const; + API_FUNCTION() const Variant& GetValue(const StringView& name) const; /// /// Sets the value of the global variable (it must be added first). diff --git a/Source/Engine/Level/Actors/AnimatedModel.cpp b/Source/Engine/Level/Actors/AnimatedModel.cpp index 17b9acc11..2c0e8474d 100644 --- a/Source/Engine/Level/Actors/AnimatedModel.cpp +++ b/Source/Engine/Level/Actors/AnimatedModel.cpp @@ -273,7 +273,7 @@ AnimGraphParameter* AnimatedModel::GetParameter(const StringView& name) return nullptr; } -Variant AnimatedModel::GetParameterValue(const StringView& name) +const Variant& AnimatedModel::GetParameterValue(const StringView& name) const { CHECK_ANIM_GRAPH_PARAM_ACCESS_RESULT(Variant::Null); for (auto& param : GraphInstance.Parameters) @@ -299,7 +299,7 @@ void AnimatedModel::SetParameterValue(const StringView& name, const Variant& val LOG(Warning, "Failed to set animated model '{0}' missing parameter '{1}'", ToString(), name); } -Variant AnimatedModel::GetParameterValue(const Guid& id) +const Variant& AnimatedModel::GetParameterValue(const Guid& id) const { CHECK_ANIM_GRAPH_PARAM_ACCESS_RESULT(Variant::Null); for (auto& param : GraphInstance.Parameters) diff --git a/Source/Engine/Level/Actors/AnimatedModel.h b/Source/Engine/Level/Actors/AnimatedModel.h index bb475722a..bb4b3a8f0 100644 --- a/Source/Engine/Level/Actors/AnimatedModel.h +++ b/Source/Engine/Level/Actors/AnimatedModel.h @@ -308,7 +308,7 @@ public: /// /// The parameter name. /// The value. - API_FUNCTION() Variant GetParameterValue(const StringView& name); + API_FUNCTION() const Variant& GetParameterValue(const StringView& name) const; /// /// Sets the anim graph instance parameter value. @@ -322,7 +322,7 @@ public: /// /// The parameter id. /// The value. - API_FUNCTION() Variant GetParameterValue(const Guid& id); + API_FUNCTION() const Variant& GetParameterValue(const Guid& id) const; /// /// Sets the anim graph instance parameter value. diff --git a/Source/Engine/Particles/ParticleEffect.cpp b/Source/Engine/Particles/ParticleEffect.cpp index ab3066372..9fbab80b9 100644 --- a/Source/Engine/Particles/ParticleEffect.cpp +++ b/Source/Engine/Particles/ParticleEffect.cpp @@ -91,14 +91,14 @@ Variant ParticleEffectParameter::GetDefaultValue() const return paramValue; } -Variant ParticleEffectParameter::GetDefaultEmitterValue() const +const Variant& ParticleEffectParameter::GetDefaultEmitterValue() const { CHECK_RETURN(IsValid(), Variant::False); const ParticleSystemParameter& param = _effect->ParticleSystem->Emitters[_emitterIndex]->Graph.Parameters[_paramIndex]; return param.Value; } -Variant ParticleEffectParameter::GetValue() const +const Variant& ParticleEffectParameter::GetValue() const { CHECK_RETURN(IsValid(), Variant::False); const Variant& paramValue = _effect->Instance.Emitters[_emitterIndex].Parameters[_paramIndex]; @@ -205,7 +205,7 @@ ParticleEffectParameter* ParticleEffect::GetParameter(const StringView& emitterT return nullptr; } -Variant ParticleEffect::GetParameterValue(const StringView& emitterTrackName, const StringView& paramName) +const Variant& ParticleEffect::GetParameterValue(const StringView& emitterTrackName, const StringView& paramName) { const auto param = GetParameter(emitterTrackName, paramName); CHECK_RETURN(param, Variant::Null); diff --git a/Source/Engine/Particles/ParticleEffect.h b/Source/Engine/Particles/ParticleEffect.h index 5e2770f89..a338bfee2 100644 --- a/Source/Engine/Particles/ParticleEffect.h +++ b/Source/Engine/Particles/ParticleEffect.h @@ -109,13 +109,13 @@ public: /// Gets the default value of the parameter (set in particle emitter asset). /// /// The default value. - API_PROPERTY() Variant GetDefaultEmitterValue() const; + API_PROPERTY() const Variant& GetDefaultEmitterValue() const; /// /// Gets the value of the parameter. /// /// The value. - API_PROPERTY() Variant GetValue() const; + API_PROPERTY() const Variant& GetValue() const; /// /// Sets the value of the parameter. @@ -293,7 +293,7 @@ public: /// The emitter track name (in particle system asset). /// The emitter parameter name (in particle emitter asset). /// The value. - API_FUNCTION() Variant GetParameterValue(const StringView& emitterTrackName, const StringView& paramName); + API_FUNCTION() const Variant& GetParameterValue(const StringView& emitterTrackName, const StringView& paramName); /// /// Set the particle parameter value. From 272977a521ede5c3ea7cd92d1d52115321e54726 Mon Sep 17 00:00:00 2001 From: Ari Vuollet Date: Sat, 1 Jun 2024 20:24:57 +0300 Subject: [PATCH 06/11] Defer Editor EndInit after loading scripting assemblies Assets containing deserialized data of scripting assembly structures needs to be loaded after the scripting assemblies have been loaded. --- Source/Editor/Managed/ManagedEditor.cpp | 13 +++++++++++++ Source/Editor/States/LoadingState.cs | 1 - 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/Source/Editor/Managed/ManagedEditor.cpp b/Source/Editor/Managed/ManagedEditor.cpp index c4c71bdfd..d0b060ffe 100644 --- a/Source/Editor/Managed/ManagedEditor.cpp +++ b/Source/Editor/Managed/ManagedEditor.cpp @@ -223,6 +223,19 @@ void ManagedEditor::Init() { LOG(Info, "Loading managed assemblies (due to disabled compilation on startup)"); Scripting::Load(); + + const auto endInitMethod = mclass->GetMethod("EndInit"); + if (endInitMethod == nullptr) + { + LOG(Fatal, "Invalid Editor assembly! Missing EndInit method."); + } + endInitMethod->Invoke(instance, nullptr, &exception); + if (exception) + { + MException ex(exception); + ex.Log(LogType::Warning, TEXT("ManagedEditor::EndInit")); + LOG_STR(Fatal, TEXT("Failed to initialize editor during EndInit! ") + ex.Message); + } } // Call building if need to (based on CL) diff --git a/Source/Editor/States/LoadingState.cs b/Source/Editor/States/LoadingState.cs index 44a4c7f28..93495f750 100644 --- a/Source/Editor/States/LoadingState.cs +++ b/Source/Editor/States/LoadingState.cs @@ -71,7 +71,6 @@ namespace FlaxEditor.States { // Skip compilation on startup OnCompilationEnd(true); - Editor.EndInit(); } } From fef124a01dcbb06f938f747aacf2cea71ccaaa86 Mon Sep 17 00:00:00 2001 From: Ari Vuollet Date: Sat, 1 Jun 2024 21:36:22 +0300 Subject: [PATCH 07/11] Fix crash when trying to import unsupported EXR-file --- Source/Engine/Tools/TextureTool/TextureTool.DirectXTex.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Engine/Tools/TextureTool/TextureTool.DirectXTex.cpp b/Source/Engine/Tools/TextureTool/TextureTool.DirectXTex.cpp index cec543d05..31b20fea2 100644 --- a/Source/Engine/Tools/TextureTool/TextureTool.DirectXTex.cpp +++ b/Source/Engine/Tools/TextureTool/TextureTool.DirectXTex.cpp @@ -306,7 +306,7 @@ HRESULT LoadFromEXRFile(const StringView& path, DirectX::ScratchImage& image) LOG_STR(Warning, String(err)); FreeEXRErrorMessage(err); } - return S_FALSE; + return E_FAIL; } // Setup image @@ -326,7 +326,7 @@ HRESULT LoadFromEXRFile(const StringView& path, DirectX::ScratchImage& image) return result; #else LOG(Warning, "EXR format is not supported."); - return S_FALSE; + return E_FAIL; #endif } From db71bf28682dc4200ad37245b8b94c041d6372e1 Mon Sep 17 00:00:00 2001 From: Ari Vuollet Date: Sun, 10 Mar 2024 16:40:35 +0200 Subject: [PATCH 08/11] Store Debug Log view options in Editor options --- Source/Editor/Options/InterfaceOptions.cs | 101 ++++++++++++++++------ Source/Editor/Windows/DebugLogWindow.cs | 50 ++++++++--- 2 files changed, 115 insertions(+), 36 deletions(-) diff --git a/Source/Editor/Options/InterfaceOptions.cs b/Source/Editor/Options/InterfaceOptions.cs index 7fa08cc39..360d1a7ed 100644 --- a/Source/Editor/Options/InterfaceOptions.cs +++ b/Source/Editor/Options/InterfaceOptions.cs @@ -175,13 +175,6 @@ namespace FlaxEditor.Options [EditorDisplay("Interface", "New Window Location"), EditorOrder(150), Tooltip("Define the opening method for new windows, open in a new tab by default.")] public DockStateProxy NewWindowLocation { get; set; } = DockStateProxy.Float; - /// - /// Gets or sets the timestamps prefix mode for debug log messages. - /// - [DefaultValue(TimestampsFormats.None)] - [EditorDisplay("Interface"), EditorOrder(210), Tooltip("The timestamps prefix mode for debug log messages.")] - public TimestampsFormats DebugLogTimestampsFormat { get; set; } = TimestampsFormats.None; - /// /// Gets or sets the editor icons scale. Editor restart required. /// @@ -220,21 +213,70 @@ namespace FlaxEditor.Options /// /// Gets or sets the timestamps prefix mode for output log messages. /// - [DefaultValue(TimestampsFormats.TimeSinceStartup)] - [EditorDisplay("Output Log", "Timestamps Format"), EditorOrder(300), Tooltip("The timestamps prefix mode for output log messages.")] - public TimestampsFormats OutputLogTimestampsFormat { get; set; } = TimestampsFormats.TimeSinceStartup; + [DefaultValue(TimestampsFormats.None)] + [EditorDisplay("Debug Log"), EditorOrder(350), Tooltip("The timestamps prefix mode for debug log messages.")] + public TimestampsFormats DebugLogTimestampsFormat { get; set; } = TimestampsFormats.None; + + /// + /// Gets or sets the clear on play for debug log messages. + /// + [DefaultValue(true)] + [EditorDisplay("Debug Log", "Clear on Play"), EditorOrder(360), Tooltip("Clears all log entries on enter playmode.")] + public bool DebugLogClearOnPlay { get; set; } = true; + + /// + /// Gets or sets the collapse mode for debug log messages. + /// + [DefaultValue(true)] + [EditorDisplay("Debug Log"), EditorOrder(361), Tooltip("Collapses similar or repeating log entries.")] + public bool DebugLogCollapse { get; set; } = true; + + /// + /// Gets or sets the automatic pause on error for debug log messages. + /// + [DefaultValue(false)] + [EditorDisplay("Debug Log", "Pause on Error"), EditorOrder(362), Tooltip("Performs auto pause on error.")] + public bool DebugLogPauseOnError { get; set; } = false; + + /// + /// Gets or sets the automatic pause on error for debug log messages. + /// + [DefaultValue(true)] + [EditorDisplay("Debug Log", "Show error messages"), EditorOrder(370), Tooltip("Shows/hides error messages.")] + public bool DebugLogShowErrorMessages { get; set; } = true; + + /// + /// Gets or sets the automatic pause on error for debug log messages. + /// + [DefaultValue(true)] + [EditorDisplay("Debug Log", "Show warning messages"), EditorOrder(371), Tooltip("Shows/hides warning messages.")] + public bool DebugLogShowWarningMessages { get; set; } = true; + + /// + /// Gets or sets the automatic pause on error for debug log messages. + /// + [DefaultValue(true)] + [EditorDisplay("Debug Log", "Show info messages"), EditorOrder(372), Tooltip("Shows/hides info messages.")] + public bool DebugLogShowInfoMessages { get; set; } = true; /// /// Gets or sets the timestamps prefix mode for output log messages. /// + [DefaultValue(TimestampsFormats.TimeSinceStartup)] + [EditorDisplay("Output Log", "Timestamps Format"), EditorOrder(400), Tooltip("The timestamps prefix mode for output log messages.")] + public TimestampsFormats OutputLogTimestampsFormat { get; set; } = TimestampsFormats.TimeSinceStartup; + + /// + /// Gets or sets the log type prefix mode for output log messages. + /// [DefaultValue(true)] - [EditorDisplay("Output Log", "Show Log Type"), EditorOrder(310), Tooltip("Determines whether show log type prefix in output log messages.")] + [EditorDisplay("Output Log", "Show Log Type"), EditorOrder(410), Tooltip("Determines whether show log type prefix in output log messages.")] public bool OutputLogShowLogType { get; set; } = true; /// /// Gets or sets the output log text font. /// - [EditorDisplay("Output Log", "Text Font"), EditorOrder(320), Tooltip("The output log text font.")] + [EditorDisplay("Output Log", "Text Font"), EditorOrder(420), Tooltip("The output log text font.")] public FontReference OutputLogTextFont { get => _outputLogFont; @@ -253,63 +295,70 @@ namespace FlaxEditor.Options /// Gets or sets the output log text color. /// [DefaultValue(typeof(Color), "1,1,1,1")] - [EditorDisplay("Output Log", "Text Color"), EditorOrder(330), Tooltip("The output log text color.")] + [EditorDisplay("Output Log", "Text Color"), EditorOrder(430), Tooltip("The output log text color.")] public Color OutputLogTextColor { get; set; } = Color.White; /// /// Gets or sets the output log text shadow color. /// [DefaultValue(typeof(Color), "0,0,0,0.5")] - [EditorDisplay("Output Log", "Text Shadow Color"), EditorOrder(340), Tooltip("The output log text shadow color.")] + [EditorDisplay("Output Log", "Text Shadow Color"), EditorOrder(440), Tooltip("The output log text shadow color.")] public Color OutputLogTextShadowColor { get; set; } = new Color(0, 0, 0, 0.5f); /// /// Gets or sets the output log text shadow offset. Set to 0 to disable this feature. /// [DefaultValue(typeof(Float2), "1,1")] - [EditorDisplay("Output Log", "Text Shadow Offset"), EditorOrder(340), Tooltip("The output log text shadow offset. Set to 0 to disable this feature.")] + [EditorDisplay("Output Log", "Text Shadow Offset"), EditorOrder(445), Tooltip("The output log text shadow offset. Set to 0 to disable this feature.")] public Float2 OutputLogTextShadowOffset { get; set; } = new Float2(1); /// /// Gets or sets a value indicating whether auto-focus output log window on code compilation error. /// [DefaultValue(true)] - [EditorDisplay("Output Log", "Focus Output Log On Compilation Error"), EditorOrder(350), Tooltip("Determines whether auto-focus output log window on code compilation error.")] + [EditorDisplay("Output Log", "Focus Output Log On Compilation Error"), EditorOrder(450), Tooltip("Determines whether auto-focus output log window on code compilation error.")] public bool FocusOutputLogOnCompilationError { get; set; } = true; /// /// Gets or sets a value indicating whether auto-focus output log window on game build error. /// [DefaultValue(true)] - [EditorDisplay("Output Log", "Focus Output Log On Game Build Error"), EditorOrder(360), Tooltip("Determines whether auto-focus output log window on game build error.")] + [EditorDisplay("Output Log", "Focus Output Log On Game Build Error"), EditorOrder(460), Tooltip("Determines whether auto-focus output log window on game build error.")] public bool FocusOutputLogOnGameBuildError { get; set; } = true; + /// + /// Gets or sets the value for automatic scroll to bottom in output log. + /// + [DefaultValue(true)] + [EditorDisplay("Output Log", "Scroll to bottom"), EditorOrder(470), Tooltip("Scroll the output log view to bottom automatically after new lines are added.")] + public bool OutputLogScrollToBottom { get; set; } = true; + /// /// Gets or sets a value indicating whether auto-focus game window on play mode start. /// [DefaultValue(true)] - [EditorDisplay("Play In-Editor", "Focus Game Window On Play"), EditorOrder(400), Tooltip("Determines whether auto-focus game window on play mode start.")] + [EditorDisplay("Play In-Editor", "Focus Game Window On Play"), EditorOrder(500), Tooltip("Determines whether auto-focus game window on play mode start.")] public bool FocusGameWinOnPlay { get; set; } = true; /// /// Gets or sets a value indicating what action should be taken upon pressing the play button. /// [DefaultValue(PlayAction.PlayScenes)] - [EditorDisplay("Play In-Editor", "Play Button Action"), EditorOrder(410)] + [EditorDisplay("Play In-Editor", "Play Button Action"), EditorOrder(510)] public PlayAction PlayButtonAction { get; set; } = PlayAction.PlayScenes; /// /// Gets or sets a value indicating how the game window should be displayed when the game is launched. /// [DefaultValue(GameWindowMode.Docked)] - [EditorDisplay("Play In-Editor", "Game Window Mode"), EditorOrder(420), Tooltip("Determines how the game window is displayed when the game is launched.")] + [EditorDisplay("Play In-Editor", "Game Window Mode"), EditorOrder(520), Tooltip("Determines how the game window is displayed when the game is launched.")] public GameWindowMode DefaultGameWindowMode { get; set; } = GameWindowMode.Docked; /// /// Gets or sets a value indicating the number of game clients to launch when building and/or running cooked game. /// [DefaultValue(1), Range(1, 4)] - [EditorDisplay("Cook & Run"), EditorOrder(500)] + [EditorDisplay("Cook & Run"), EditorOrder(600)] public int NumberOfGameClientsToLaunch = 1; /// @@ -331,13 +380,13 @@ namespace FlaxEditor.Options /// /// The list of fallback fonts to use when main text font is missing certain characters. Empty to use fonts from GraphicsSettings. /// - [EditorDisplay("Fonts"), EditorOrder(650)] + [EditorDisplay("Fonts"), EditorOrder(750)] public FontAsset[] FallbackFonts = new FontAsset[1] { FlaxEngine.Content.LoadAsyncInternal(EditorAssets.FallbackFont) }; /// /// Gets or sets the title font for editor UI. /// - [EditorDisplay("Fonts"), EditorOrder(600), Tooltip("The title font for editor UI.")] + [EditorDisplay("Fonts"), EditorOrder(700), Tooltip("The title font for editor UI.")] public FontReference TitleFont { get => _titleFont; @@ -355,7 +404,7 @@ namespace FlaxEditor.Options /// /// Gets or sets the large font for editor UI. /// - [EditorDisplay("Fonts"), EditorOrder(610), Tooltip("The large font for editor UI.")] + [EditorDisplay("Fonts"), EditorOrder(710), Tooltip("The large font for editor UI.")] public FontReference LargeFont { get => _largeFont; @@ -373,7 +422,7 @@ namespace FlaxEditor.Options /// /// Gets or sets the medium font for editor UI. /// - [EditorDisplay("Fonts"), EditorOrder(620), Tooltip("The medium font for editor UI.")] + [EditorDisplay("Fonts"), EditorOrder(720), Tooltip("The medium font for editor UI.")] public FontReference MediumFont { get => _mediumFont; @@ -391,7 +440,7 @@ namespace FlaxEditor.Options /// /// Gets or sets the small font for editor UI. /// - [EditorDisplay("Fonts"), EditorOrder(630), Tooltip("The small font for editor UI.")] + [EditorDisplay("Fonts"), EditorOrder(730), Tooltip("The small font for editor UI.")] public FontReference SmallFont { get => _smallFont; diff --git a/Source/Editor/Windows/DebugLogWindow.cs b/Source/Editor/Windows/DebugLogWindow.cs index 12a2553c3..88c19dc32 100644 --- a/Source/Editor/Windows/DebugLogWindow.cs +++ b/Source/Editor/Windows/DebugLogWindow.cs @@ -318,7 +318,6 @@ namespace FlaxEditor.Windows { Title = "Debug Log"; Icon = IconInfo; - OnEditorOptionsChanged(Editor.Options.Options); FlaxEditor.Utilities.Utils.SetupCommonInputActions(this); // Toolstrip @@ -327,17 +326,42 @@ namespace FlaxEditor.Windows Parent = this, }; toolstrip.AddButton("Clear", Clear).LinkTooltip("Clears all log entries"); - _clearOnPlayButton = (ToolStripButton)toolstrip.AddButton("Clear on Play").SetAutoCheck(true).SetChecked(true).LinkTooltip("Clears all log entries on enter playmode"); - bool collapse = true; - if (Editor.ProjectCache.TryGetCustomData("DebugLogCollapse", out bool setCollapse)) - collapse = setCollapse; - _collapseLogsButton = (ToolStripButton)toolstrip.AddButton("Collapse", () => Editor.ProjectCache.SetCustomData("DebugLogCollapse", _collapseLogsButton.Checked.ToString())).SetAutoCheck(true).SetChecked(collapse).LinkTooltip("Collapses similar logs."); - _pauseOnErrorButton = (ToolStripButton)toolstrip.AddButton("Pause on Error").SetAutoCheck(true).LinkTooltip("Performs auto pause on error"); + _clearOnPlayButton = (ToolStripButton)toolstrip.AddButton("Clear on Play", () => + { + editor.Options.Options.Interface.DebugLogClearOnPlay = _clearOnPlayButton.Checked; + editor.Options.Apply(editor.Options.Options); + }).SetAutoCheck(true).LinkTooltip("Clears all log entries on enter playmode"); + _collapseLogsButton = (ToolStripButton)toolstrip.AddButton("Collapse", () => + { + editor.Options.Options.Interface.DebugLogCollapse = _collapseLogsButton.Checked; + editor.Options.Apply(editor.Options.Options); + }).SetAutoCheck(true).LinkTooltip("Collapses similar logs."); + _pauseOnErrorButton = (ToolStripButton)toolstrip.AddButton("Pause on Error", () => + { + editor.Options.Options.Interface.DebugLogPauseOnError = _pauseOnErrorButton.Checked; + editor.Options.Apply(editor.Options.Options); + }).SetAutoCheck(true).LinkTooltip("Performs auto pause on error"); toolstrip.AddSeparator(); - _groupButtons[0] = (ToolStripButton)toolstrip.AddButton(editor.Icons.Error32, () => UpdateLogTypeVisibility(LogGroup.Error, _groupButtons[0].Checked)).SetAutoCheck(true).SetChecked(true).LinkTooltip("Shows/hides error messages"); - _groupButtons[1] = (ToolStripButton)toolstrip.AddButton(editor.Icons.Warning32, () => UpdateLogTypeVisibility(LogGroup.Warning, _groupButtons[1].Checked)).SetAutoCheck(true).SetChecked(true).LinkTooltip("Shows/hides warning messages"); - _groupButtons[2] = (ToolStripButton)toolstrip.AddButton(editor.Icons.Info32, () => UpdateLogTypeVisibility(LogGroup.Info, _groupButtons[2].Checked)).SetAutoCheck(true).SetChecked(true).LinkTooltip("Shows/hides info messages"); + _groupButtons[0] = (ToolStripButton)toolstrip.AddButton(editor.Icons.Error32, () => + { + UpdateLogTypeVisibility(LogGroup.Error, _groupButtons[0].Checked); + editor.Options.Options.Interface.DebugLogShowErrorMessages = _groupButtons[0].Checked; + editor.Options.Apply(editor.Options.Options); + }).SetAutoCheck(true).LinkTooltip("Shows/hides error messages"); + _groupButtons[1] = (ToolStripButton)toolstrip.AddButton(editor.Icons.Warning32, () => + { + UpdateLogTypeVisibility(LogGroup.Warning, _groupButtons[1].Checked); + editor.Options.Options.Interface.DebugLogShowWarningMessages = _groupButtons[1].Checked; + editor.Options.Apply(editor.Options.Options); + }).SetAutoCheck(true).LinkTooltip("Shows/hides warning messages"); + _groupButtons[2] = (ToolStripButton)toolstrip.AddButton(editor.Icons.Info32, () => + { + UpdateLogTypeVisibility(LogGroup.Info, _groupButtons[2].Checked); + editor.Options.Options.Interface.DebugLogShowInfoMessages = _groupButtons[2].Checked; + editor.Options.Apply(editor.Options.Options); + }).SetAutoCheck(true).LinkTooltip("Shows/hides info messages"); UpdateCount(); + OnEditorOptionsChanged(Editor.Options.Options); // Split panel _split = new SplitPanel(Orientation.Vertical, ScrollBars.Vertical, ScrollBars.Both) @@ -383,6 +407,12 @@ namespace FlaxEditor.Windows private void OnEditorOptionsChanged(EditorOptions options) { _timestampsFormats = options.Interface.DebugLogTimestampsFormat; + _clearOnPlayButton.Checked = options.Interface.DebugLogClearOnPlay; + _collapseLogsButton.Checked = options.Interface.DebugLogCollapse; + _pauseOnErrorButton.Checked = options.Interface.DebugLogPauseOnError; + _groupButtons[0].Checked = options.Interface.DebugLogShowErrorMessages; + _groupButtons[1].Checked = options.Interface.DebugLogShowWarningMessages; + _groupButtons[2].Checked = options.Interface.DebugLogShowInfoMessages; } /// From 86d90605fc1448dd6e032ed38cfba24c3e9dc0dc Mon Sep 17 00:00:00 2001 From: Ari Vuollet Date: Sun, 10 Mar 2024 16:42:02 +0200 Subject: [PATCH 09/11] Fix Editor options data applying in realtime after first save Reclone the data in order to not modify the currently applied options data after save. --- Source/Editor/Windows/EditorOptionsWindow.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Editor/Windows/EditorOptionsWindow.cs b/Source/Editor/Windows/EditorOptionsWindow.cs index e9c4385b5..c8a5338e7 100644 --- a/Source/Editor/Windows/EditorOptionsWindow.cs +++ b/Source/Editor/Windows/EditorOptionsWindow.cs @@ -162,7 +162,7 @@ namespace FlaxEditor.Windows Editor.Options.Apply(_options); - ClearDirtyFlag(); + GatherData(); } private void SetupCustomTabs() From c4d5e50f2278e1c5b9629b146d8ca07eb33bb46f Mon Sep 17 00:00:00 2001 From: Ari Vuollet Date: Sun, 10 Mar 2024 16:42:12 +0200 Subject: [PATCH 10/11] Update Editor options when window is shown --- Source/Editor/Windows/EditorOptionsWindow.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Source/Editor/Windows/EditorOptionsWindow.cs b/Source/Editor/Windows/EditorOptionsWindow.cs index c8a5338e7..17314f164 100644 --- a/Source/Editor/Windows/EditorOptionsWindow.cs +++ b/Source/Editor/Windows/EditorOptionsWindow.cs @@ -234,6 +234,18 @@ namespace FlaxEditor.Windows base.OnDestroy(); } + /// + protected override void OnShow() + { + if (!_isDataDirty) + { + // Refresh the data, skip when data is modified during window docking + GatherData(); + } + + base.OnShow(); + } + /// protected override bool OnClosing(ClosingReason reason) { From f51a44235795ed25caf94a705d8da3aa84d053c0 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Mon, 3 Jun 2024 10:54:22 +0200 Subject: [PATCH 11/11] Fix crash when using content search in Visject surface --- Source/Editor/Surface/Archetypes/Function.cs | 26 +++++++++++--------- Source/Editor/Surface/Elements/FloatValue.cs | 2 +- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/Source/Editor/Surface/Archetypes/Function.cs b/Source/Editor/Surface/Archetypes/Function.cs index 4a66d2675..11dd12765 100644 --- a/Source/Editor/Surface/Archetypes/Function.cs +++ b/Source/Editor/Surface/Archetypes/Function.cs @@ -2198,21 +2198,23 @@ namespace FlaxEditor.Surface.Archetypes _combobox.ClearItems(); _tooltips.Clear(); _functionNodesIds.Clear(); - var nodes = Surface.Nodes; - var count = _signature != null ? nodes.Count : 0; - for (int i = 0; i < count; i++) + if (Surface != null && _signature != null) { - if (nodes[i] is VisualScriptFunctionNode functionNode) + var nodes = Surface.Nodes; + for (int i = 0; i < nodes.Count; i++) { - // Get if function signature matches the event signature - functionNode.GetSignature(out var functionSig); - if (IsValidFunctionSignature(ref functionSig)) + if (nodes[i] is VisualScriptFunctionNode functionNode) { - if (functionNode.ID == handlerFunctionNodeId) - toSelect = _functionNodesIds.Count; - _functionNodesIds.Add(functionNode.ID); - _tooltips.Add(functionNode.TooltipText); - _combobox.AddItem(functionSig.ToString()); + // Get if function signature matches the event signature + functionNode.GetSignature(out var functionSig); + if (IsValidFunctionSignature(ref functionSig)) + { + if (functionNode.ID == handlerFunctionNodeId) + toSelect = _functionNodesIds.Count; + _functionNodesIds.Add(functionNode.ID); + _tooltips.Add(functionNode.TooltipText); + _combobox.AddItem(functionSig.ToString()); + } } } } diff --git a/Source/Editor/Surface/Elements/FloatValue.cs b/Source/Editor/Surface/Elements/FloatValue.cs index c5b73d297..71ee26df9 100644 --- a/Source/Editor/Surface/Elements/FloatValue.cs +++ b/Source/Editor/Surface/Elements/FloatValue.cs @@ -35,7 +35,7 @@ namespace FlaxEditor.Surface.Elements ParentNode.ValuesChanged += OnNodeValuesChanged; // Disable slider if surface doesn't allow it - if (!ParentNode.Surface.CanLivePreviewValueChanges) + if (ParentNode.Surface != null && !ParentNode.Surface.CanLivePreviewValueChanges) _slideSpeed = 0.0f; }