From 3e8e839cd1b8931ceb1393c8ea4c0818e2eaa36d Mon Sep 17 00:00:00 2001 From: Wojciech Figat Date: Tue, 27 Dec 2022 13:54:53 +0100 Subject: [PATCH] Refactor Editor Windows layout serialization of splitter values to prevent invalid state when loading windows --- Source/Editor/GUI/Docking/DockWindow.cs | 24 +++++++++++++++++++ Source/Editor/Surface/VisjectSurfaceWindow.cs | 11 ++++----- .../Editor/Windows/Assets/AnimationWindow.cs | 21 ++++++++-------- .../Editor/Windows/Assets/AudioClipWindow.cs | 5 ++-- .../Windows/Assets/CollisionDataWindow.cs | 5 ++-- .../Windows/Assets/CubeTextureWindow.cs | 5 ++-- .../Windows/Assets/MaterialInstanceWindow.cs | 5 ++-- .../Editor/Windows/Assets/ModelBaseWindow.cs | 5 ++-- .../Windows/Assets/ParticleSystemWindow.cs | 17 +++++-------- Source/Editor/Windows/Assets/PrefabWindow.cs | 13 ++++------ .../Windows/Assets/SceneAnimationWindow.cs | 9 ++----- .../Windows/Assets/SkeletonMaskWindow.cs | 5 ++-- .../Windows/Assets/SpriteAtlasWindow.cs | 5 ++-- Source/Editor/Windows/Assets/TextureWindow.cs | 5 ++-- .../Windows/Assets/VisualScriptWindow.cs | 5 ++-- Source/Editor/Windows/ContentWindow.cs | 13 ++++------ Source/Editor/Windows/DebugLogWindow.cs | 5 ++-- 17 files changed, 75 insertions(+), 83 deletions(-) diff --git a/Source/Editor/GUI/Docking/DockWindow.cs b/Source/Editor/GUI/Docking/DockWindow.cs index de5ccf206..b7fcb5427 100644 --- a/Source/Editor/GUI/Docking/DockWindow.cs +++ b/Source/Editor/GUI/Docking/DockWindow.cs @@ -1,6 +1,7 @@ // Copyright (c) 2012-2022 Wojciech Figat. All rights reserved. using System.Xml; +using System.Globalization; using FlaxEngine; using FlaxEngine.Assertions; using FlaxEngine.GUI; @@ -423,6 +424,29 @@ namespace FlaxEditor.GUI.Docking { } + /// + /// Serializes splitter panel value into the saved layout. + /// + /// The Xml writer. + /// The Xml attribute name to use for value. + /// The splitter panel. + protected void LayoutSerializeSplitter(XmlWriter writer, string name, SplitPanel splitter) + { + writer.WriteAttributeString(name, splitter.SplitterValue.ToString(CultureInfo.InvariantCulture)); + } + + /// + /// Deserializes splitter panel value from the saved layout. + /// + /// The Xml document node. + /// The Xml attribute name to use for value. + /// The splitter panel. + protected void LayoutDeserializeSplitter(XmlElement node, string name, SplitPanel splitter) + { + if (float.TryParse(node.GetAttribute(name), CultureInfo.InvariantCulture, out float value) && value > 0.01f && value < 0.99f) + splitter.SplitterValue = value; + } + /// public override void OnDestroy() { diff --git a/Source/Editor/Surface/VisjectSurfaceWindow.cs b/Source/Editor/Surface/VisjectSurfaceWindow.cs index 43a664866..d79fc8a90 100644 --- a/Source/Editor/Surface/VisjectSurfaceWindow.cs +++ b/Source/Editor/Surface/VisjectSurfaceWindow.cs @@ -1000,18 +1000,15 @@ namespace FlaxEditor.Surface /// public override void OnLayoutSerialize(XmlWriter writer) { - writer.WriteAttributeString("Split1", _split1.SplitterValue.ToString()); - writer.WriteAttributeString("Split2", _split2.SplitterValue.ToString()); + LayoutSerializeSplitter(writer, "Split1", _split1); + LayoutSerializeSplitter(writer, "Split2", _split2); } /// public override void OnLayoutDeserialize(XmlElement node) { - if (float.TryParse(node.GetAttribute("Split1"), out float value1)) - _split1.SplitterValue = value1; - - if (float.TryParse(node.GetAttribute("Split2"), out value1)) - _split2.SplitterValue = value1; + LayoutDeserializeSplitter(node, "Split1", _split1); + LayoutDeserializeSplitter(node, "Split2", _split2); } /// diff --git a/Source/Editor/Windows/Assets/AnimationWindow.cs b/Source/Editor/Windows/Assets/AnimationWindow.cs index 37560c7e0..38cf5aa68 100644 --- a/Source/Editor/Windows/Assets/AnimationWindow.cs +++ b/Source/Editor/Windows/Assets/AnimationWindow.cs @@ -1,6 +1,7 @@ // Copyright (c) 2012-2022 Wojciech Figat. All rights reserved. using System; +using System.Globalization; using System.Reflection; using System.Xml; using FlaxEditor.Content; @@ -374,12 +375,12 @@ namespace FlaxEditor.Windows.Assets /// public override void OnLayoutSerialize(XmlWriter writer) { - writer.WriteAttributeString("TimelineSplitter", _timeline.Splitter.SplitterValue.ToString()); + LayoutSerializeSplitter(writer, "TimelineSplitter", _timeline.Splitter); + LayoutSerializeSplitter(writer, "Panel1Splitter", _panel1); + if (_panel2 != null) + LayoutSerializeSplitter(writer, "Panel2Splitter", _panel2); writer.WriteAttributeString("TimeShowMode", _timeline.TimeShowMode.ToString()); writer.WriteAttributeString("ShowPreviewValues", _timeline.ShowPreviewValues.ToString()); - writer.WriteAttributeString("Panel1Splitter", _panel1.SplitterValue.ToString()); - if (_panel2 != null) - writer.WriteAttributeString("Panel2Splitter", _panel2.SplitterValue.ToString()); if (_properties.PreviewModel) writer.WriteAttributeString("PreviewModel", _properties.PreviewModel.ID.ToString()); } @@ -387,18 +388,16 @@ namespace FlaxEditor.Windows.Assets /// public override void OnLayoutDeserialize(XmlElement node) { - if (Guid.TryParse(node.GetAttribute("PreviewModel"), out Guid value4)) - _initialPreviewModel = FlaxEngine.Content.LoadAsync(value4); - if (float.TryParse(node.GetAttribute("TimelineSplitter"), out float value1)) - _timeline.Splitter.SplitterValue = value1; - if (float.TryParse(node.GetAttribute("Panel1Splitter"), out value1)) - _panel1.SplitterValue = value1; - if (float.TryParse(node.GetAttribute("Panel2Splitter"), out value1)) + LayoutDeserializeSplitter(node, "TimelineSplitter", _timeline.Splitter); + LayoutDeserializeSplitter(node, "Panel1Splitter", _panel1); + if (float.TryParse(node.GetAttribute("Panel2Splitter"), CultureInfo.InvariantCulture, out float value1) && value1 > 0.01f && value1 < 0.99f) _initialPanel2Splitter = value1; if (Enum.TryParse(node.GetAttribute("TimeShowMode"), out Timeline.TimeShowModes value2)) _timeline.TimeShowMode = value2; if (bool.TryParse(node.GetAttribute("ShowPreviewValues"), out bool value3)) _timeline.ShowPreviewValues = value3; + if (Guid.TryParse(node.GetAttribute("PreviewModel"), out Guid value4)) + _initialPreviewModel = FlaxEngine.Content.LoadAsync(value4); } /// diff --git a/Source/Editor/Windows/Assets/AudioClipWindow.cs b/Source/Editor/Windows/Assets/AudioClipWindow.cs index f8c5164a3..2f4b1a315 100644 --- a/Source/Editor/Windows/Assets/AudioClipWindow.cs +++ b/Source/Editor/Windows/Assets/AudioClipWindow.cs @@ -282,14 +282,13 @@ namespace FlaxEditor.Windows.Assets /// public override void OnLayoutSerialize(XmlWriter writer) { - writer.WriteAttributeString("Split", _split.SplitterValue.ToString()); + LayoutSerializeSplitter(writer, "Split", _split); } /// public override void OnLayoutDeserialize(XmlElement node) { - if (float.TryParse(node.GetAttribute("Split"), out float value1)) - _split.SplitterValue = value1; + LayoutDeserializeSplitter(node, "Split", _split); } /// diff --git a/Source/Editor/Windows/Assets/CollisionDataWindow.cs b/Source/Editor/Windows/Assets/CollisionDataWindow.cs index bd6d1ab3a..3f5fb9d37 100644 --- a/Source/Editor/Windows/Assets/CollisionDataWindow.cs +++ b/Source/Editor/Windows/Assets/CollisionDataWindow.cs @@ -317,14 +317,13 @@ namespace FlaxEditor.Windows.Assets /// public override void OnLayoutSerialize(XmlWriter writer) { - writer.WriteAttributeString("Split", _split.SplitterValue.ToString()); + LayoutSerializeSplitter(writer, "Split", _split); } /// public override void OnLayoutDeserialize(XmlElement node) { - if (float.TryParse(node.GetAttribute("Split"), out float value1)) - _split.SplitterValue = value1; + LayoutDeserializeSplitter(node, "Split", _split); } /// diff --git a/Source/Editor/Windows/Assets/CubeTextureWindow.cs b/Source/Editor/Windows/Assets/CubeTextureWindow.cs index 845b40ee1..76baec074 100644 --- a/Source/Editor/Windows/Assets/CubeTextureWindow.cs +++ b/Source/Editor/Windows/Assets/CubeTextureWindow.cs @@ -206,14 +206,13 @@ namespace FlaxEditor.Windows.Assets /// public override void OnLayoutSerialize(XmlWriter writer) { - writer.WriteAttributeString("Split", _split.SplitterValue.ToString()); + LayoutSerializeSplitter(writer, "Split", _split); } /// public override void OnLayoutDeserialize(XmlElement node) { - if (float.TryParse(node.GetAttribute("Split"), out float value1)) - _split.SplitterValue = value1; + LayoutDeserializeSplitter(node, "Split", _split); } /// diff --git a/Source/Editor/Windows/Assets/MaterialInstanceWindow.cs b/Source/Editor/Windows/Assets/MaterialInstanceWindow.cs index 977416fcd..cd9de7e9d 100644 --- a/Source/Editor/Windows/Assets/MaterialInstanceWindow.cs +++ b/Source/Editor/Windows/Assets/MaterialInstanceWindow.cs @@ -548,14 +548,13 @@ namespace FlaxEditor.Windows.Assets /// public override void OnLayoutSerialize(XmlWriter writer) { - writer.WriteAttributeString("Split", _split.SplitterValue.ToString()); + LayoutSerializeSplitter(writer, "Split", _split); } /// public override void OnLayoutDeserialize(XmlElement node) { - if (float.TryParse(node.GetAttribute("Split"), out float value1)) - _split.SplitterValue = value1; + LayoutDeserializeSplitter(node, "Split", _split); } /// diff --git a/Source/Editor/Windows/Assets/ModelBaseWindow.cs b/Source/Editor/Windows/Assets/ModelBaseWindow.cs index 38f8cef17..2e06a117f 100644 --- a/Source/Editor/Windows/Assets/ModelBaseWindow.cs +++ b/Source/Editor/Windows/Assets/ModelBaseWindow.cs @@ -187,14 +187,13 @@ namespace FlaxEditor.Windows.Assets /// public override void OnLayoutSerialize(XmlWriter writer) { - writer.WriteAttributeString("Split", _split.SplitterValue.ToString()); + LayoutSerializeSplitter(writer, "Split", _split); } /// public override void OnLayoutDeserialize(XmlElement node) { - if (float.TryParse(node.GetAttribute("Split"), out float value1)) - _split.SplitterValue = value1; + LayoutDeserializeSplitter(node, "Split", _split); } /// diff --git a/Source/Editor/Windows/Assets/ParticleSystemWindow.cs b/Source/Editor/Windows/Assets/ParticleSystemWindow.cs index 6fdc97f64..78d712e0f 100644 --- a/Source/Editor/Windows/Assets/ParticleSystemWindow.cs +++ b/Source/Editor/Windows/Assets/ParticleSystemWindow.cs @@ -543,22 +543,17 @@ namespace FlaxEditor.Windows.Assets /// public override void OnLayoutSerialize(XmlWriter writer) { - writer.WriteAttributeString("Split1", _split1.SplitterValue.ToString()); - writer.WriteAttributeString("Split2", _split2.SplitterValue.ToString()); - writer.WriteAttributeString("Split3", _timeline.Splitter.SplitterValue.ToString()); + LayoutSerializeSplitter(writer, "Split1", _split1); + LayoutSerializeSplitter(writer, "Split2", _split2); + LayoutSerializeSplitter(writer, "Split3", _timeline.Splitter); } /// public override void OnLayoutDeserialize(XmlElement node) { - if (float.TryParse(node.GetAttribute("Split1"), out float value1)) - _split1.SplitterValue = value1; - - if (float.TryParse(node.GetAttribute("Split2"), out value1)) - _split2.SplitterValue = value1; - - if (float.TryParse(node.GetAttribute("Split3"), out value1)) - _timeline.Splitter.SplitterValue = value1; + LayoutDeserializeSplitter(node, "Split1", _split1); + LayoutDeserializeSplitter(node, "Split2", _split2); + LayoutDeserializeSplitter(node, "Split3", _timeline.Splitter); } /// diff --git a/Source/Editor/Windows/Assets/PrefabWindow.cs b/Source/Editor/Windows/Assets/PrefabWindow.cs index 78d210592..90cf9e3d3 100644 --- a/Source/Editor/Windows/Assets/PrefabWindow.cs +++ b/Source/Editor/Windows/Assets/PrefabWindow.cs @@ -483,8 +483,8 @@ namespace FlaxEditor.Windows.Assets /// public override void OnLayoutSerialize(XmlWriter writer) { - writer.WriteAttributeString("Split1", _split1.SplitterValue.ToString()); - writer.WriteAttributeString("Split2", _split2.SplitterValue.ToString()); + LayoutSerializeSplitter(writer, "Split1", _split1); + LayoutSerializeSplitter(writer, "Split2", _split2); writer.WriteAttributeString("LiveReload", LiveReload.ToString()); writer.WriteAttributeString("GizmoMode", Viewport.TransformGizmo.ActiveMode.ToString()); } @@ -492,15 +492,10 @@ namespace FlaxEditor.Windows.Assets /// public override void OnLayoutDeserialize(XmlElement node) { - if (float.TryParse(node.GetAttribute("Split1"), out float value1)) - _split1.SplitterValue = value1; - - if (float.TryParse(node.GetAttribute("Split2"), out value1)) - _split2.SplitterValue = value1; - + LayoutDeserializeSplitter(node, "Split1", _split1); + LayoutDeserializeSplitter(node, "Split2", _split2); if (bool.TryParse(node.GetAttribute("LiveReload"), out bool value2)) LiveReload = value2; - if (Enum.TryParse(node.GetAttribute("GizmoMode"), out TransformGizmoBase.Mode value3)) Viewport.TransformGizmo.ActiveMode = value3; } diff --git a/Source/Editor/Windows/Assets/SceneAnimationWindow.cs b/Source/Editor/Windows/Assets/SceneAnimationWindow.cs index aef74e8bd..7840c2c7a 100644 --- a/Source/Editor/Windows/Assets/SceneAnimationWindow.cs +++ b/Source/Editor/Windows/Assets/SceneAnimationWindow.cs @@ -989,7 +989,7 @@ namespace FlaxEditor.Windows.Assets /// public override void OnLayoutSerialize(XmlWriter writer) { - writer.WriteAttributeString("TimelineSplitter", _timeline.Splitter.SplitterValue.ToString()); + LayoutSerializeSplitter(writer, "TimelineSplitter", _timeline.Splitter); writer.WriteAttributeString("TimeShowMode", _timeline.TimeShowMode.ToString()); var id = _previewButton.Checked ? Guid.Empty : (_timeline.Player?.ID ?? _cachedPlayerId); writer.WriteAttributeString("SelectedPlayer", id.ToString()); @@ -1000,18 +1000,13 @@ namespace FlaxEditor.Windows.Assets /// public override void OnLayoutDeserialize(XmlElement node) { - if (float.TryParse(node.GetAttribute("TimelineSplitter"), out float value1)) - _timeline.Splitter.SplitterValue = value1; - + LayoutDeserializeSplitter(node, "TimelineSplitter", _timeline.Splitter); if (Guid.TryParse(node.GetAttribute("SelectedPlayer"), out Guid value2)) _cachedPlayerId = value2; - if (Enum.TryParse(node.GetAttribute("TimeShowMode"), out Timeline.TimeShowModes value3)) _timeline.TimeShowMode = value3; - if (bool.TryParse(node.GetAttribute("ShowPreviewValues"), out bool value4)) _timeline.ShowPreviewValues = value4; - if (bool.TryParse(node.GetAttribute("ShowSelected3dTrack"), out value4)) _timeline.ShowSelected3dTrack = value4; } diff --git a/Source/Editor/Windows/Assets/SkeletonMaskWindow.cs b/Source/Editor/Windows/Assets/SkeletonMaskWindow.cs index 301ccf9b4..a537f2a0b 100644 --- a/Source/Editor/Windows/Assets/SkeletonMaskWindow.cs +++ b/Source/Editor/Windows/Assets/SkeletonMaskWindow.cs @@ -304,14 +304,13 @@ namespace FlaxEditor.Windows.Assets /// public override void OnLayoutSerialize(XmlWriter writer) { - writer.WriteAttributeString("Split", _split.SplitterValue.ToString()); + LayoutSerializeSplitter(writer, "Split", _split); } /// public override void OnLayoutDeserialize(XmlElement node) { - if (float.TryParse(node.GetAttribute("Split"), out float value1)) - _split.SplitterValue = value1; + LayoutDeserializeSplitter(node, "Split", _split); } /// diff --git a/Source/Editor/Windows/Assets/SpriteAtlasWindow.cs b/Source/Editor/Windows/Assets/SpriteAtlasWindow.cs index fc72e39e5..29aa1da08 100644 --- a/Source/Editor/Windows/Assets/SpriteAtlasWindow.cs +++ b/Source/Editor/Windows/Assets/SpriteAtlasWindow.cs @@ -366,14 +366,13 @@ namespace FlaxEditor.Windows.Assets /// public override void OnLayoutSerialize(XmlWriter writer) { - writer.WriteAttributeString("Split", _split.SplitterValue.ToString()); + LayoutSerializeSplitter(writer, "Split", _split); } /// public override void OnLayoutDeserialize(XmlElement node) { - if (float.TryParse(node.GetAttribute("Split"), out float value1)) - _split.SplitterValue = value1; + LayoutDeserializeSplitter(node, "Split", _split); } /// diff --git a/Source/Editor/Windows/Assets/TextureWindow.cs b/Source/Editor/Windows/Assets/TextureWindow.cs index 84c734365..1fc721084 100644 --- a/Source/Editor/Windows/Assets/TextureWindow.cs +++ b/Source/Editor/Windows/Assets/TextureWindow.cs @@ -245,14 +245,13 @@ namespace FlaxEditor.Windows.Assets /// public override void OnLayoutSerialize(XmlWriter writer) { - writer.WriteAttributeString("Split", _split.SplitterValue.ToString()); + LayoutSerializeSplitter(writer, "Split", _split); } /// public override void OnLayoutDeserialize(XmlElement node) { - if (float.TryParse(node.GetAttribute("Split"), out float value1)) - _split.SplitterValue = value1; + LayoutDeserializeSplitter(node, "Split", _split); } /// diff --git a/Source/Editor/Windows/Assets/VisualScriptWindow.cs b/Source/Editor/Windows/Assets/VisualScriptWindow.cs index de70ea1e2..443b8954d 100644 --- a/Source/Editor/Windows/Assets/VisualScriptWindow.cs +++ b/Source/Editor/Windows/Assets/VisualScriptWindow.cs @@ -1367,14 +1367,13 @@ namespace FlaxEditor.Windows.Assets /// public override void OnLayoutSerialize(XmlWriter writer) { - writer.WriteAttributeString("Split", _split.SplitterValue.ToString()); + LayoutSerializeSplitter(writer, "Split", _split); } /// public override void OnLayoutDeserialize(XmlElement node) { - if (float.TryParse(node.GetAttribute("Split"), out float value1)) - _split.SplitterValue = value1; + LayoutDeserializeSplitter(node, "Split", _split); } /// diff --git a/Source/Editor/Windows/ContentWindow.cs b/Source/Editor/Windows/ContentWindow.cs index 22808a1f1..0a507d0e2 100644 --- a/Source/Editor/Windows/ContentWindow.cs +++ b/Source/Editor/Windows/ContentWindow.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Xml; using FlaxEditor.Content; @@ -952,8 +953,8 @@ namespace FlaxEditor.Windows /// public override void OnLayoutSerialize(XmlWriter writer) { - writer.WriteAttributeString("Split", _split.SplitterValue.ToString()); - writer.WriteAttributeString("Scale", _view.ViewScale.ToString()); + LayoutSerializeSplitter(writer, "Split", _split); + writer.WriteAttributeString("Scale", _view.ViewScale.ToString(CultureInfo.InvariantCulture)); writer.WriteAttributeString("ShowFileExtensions", _view.ShowFileExtensions.ToString()); writer.WriteAttributeString("ViewType", _view.ViewType.ToString()); } @@ -961,15 +962,11 @@ namespace FlaxEditor.Windows /// public override void OnLayoutDeserialize(XmlElement node) { - if (float.TryParse(node.GetAttribute("Split"), out float value1)) - _split.SplitterValue = value1; - - if (float.TryParse(node.GetAttribute("Scale"), out value1)) + LayoutDeserializeSplitter(node, "Split", _split); + if (float.TryParse(node.GetAttribute("Scale"), CultureInfo.InvariantCulture, out var value1)) _view.ViewScale = value1; - if (bool.TryParse(node.GetAttribute("ShowFileExtensions"), out bool value2)) _view.ShowFileExtensions = value2; - if (Enum.TryParse(node.GetAttribute("ViewType"), out ContentViewType viewType)) _view.ViewType = viewType; } diff --git a/Source/Editor/Windows/DebugLogWindow.cs b/Source/Editor/Windows/DebugLogWindow.cs index 5aca5569a..8e775b0b0 100644 --- a/Source/Editor/Windows/DebugLogWindow.cs +++ b/Source/Editor/Windows/DebugLogWindow.cs @@ -673,14 +673,13 @@ namespace FlaxEditor.Windows /// public override void OnLayoutSerialize(XmlWriter writer) { - writer.WriteAttributeString("Split", _split.SplitterValue.ToString()); + LayoutSerializeSplitter(writer, "Split", _split); } /// public override void OnLayoutDeserialize(XmlElement node) { - if (float.TryParse(node.GetAttribute("Split"), out float value1)) - _split.SplitterValue = value1; + LayoutDeserializeSplitter(node, "Split", _split); } ///