From 53d4ea51af4ae620df77879b681969184fea49a5 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Fri, 27 Jun 2025 21:18:53 -0500 Subject: [PATCH] Add prefab UI viewport scaling. --- Source/Editor/Gizmo/UIEditorGizmo.cs | 10 + Source/Editor/Modules/UIModule.cs | 100 ++++++ .../Editor/Viewport/PrefabWindowViewport.cs | 311 +++++++++++++++++- Source/Editor/Windows/Assets/PrefabWindow.cs | 10 + Source/Editor/Windows/GameWindow.cs | 186 ++++------- 5 files changed, 501 insertions(+), 116 deletions(-) diff --git a/Source/Editor/Gizmo/UIEditorGizmo.cs b/Source/Editor/Gizmo/UIEditorGizmo.cs index bdc1c56ca..765893bed 100644 --- a/Source/Editor/Gizmo/UIEditorGizmo.cs +++ b/Source/Editor/Gizmo/UIEditorGizmo.cs @@ -155,6 +155,16 @@ namespace FlaxEditor private List _widgets; private Widget _activeWidget; + /// + /// Sets the view size. + /// + /// The new size. + public void SetViewSize(Float2 size) + { + _view.Size = size; + _view.PerformLayout(); + } + /// /// True if enable displaying UI editing background and grid elements. /// diff --git a/Source/Editor/Modules/UIModule.cs b/Source/Editor/Modules/UIModule.cs index 19a0c1142..e62dd6b6e 100644 --- a/Source/Editor/Modules/UIModule.cs +++ b/Source/Editor/Modules/UIModule.cs @@ -37,6 +37,53 @@ namespace FlaxEditor.Modules private bool _progressFailed; ContextMenuSingleSelectGroup _numberOfClientsGroup = new ContextMenuSingleSelectGroup(); + + /// + /// Defines a viewport scaling option. + /// + public class ViewportScaleOption + { + /// + /// Defines the viewport scale type. + /// + public enum ViewportScaleType + { + /// + /// Resolution. + /// + Resolution = 0, + + /// + /// Aspect Ratio. + /// + Aspect = 1, + } + + /// + /// The name. + /// + public string Label; + + /// + /// The Type of scaling to do. + /// + public ViewportScaleType ScaleType; + + /// + /// The width and height to scale by. + /// + public Int2 Size; + } + + /// + /// The default viewport scaling options. + /// + public List DefaultViewportScaleOptions = new List(); + + /// + /// The user defined viewport scaling options. + /// + public List CustomViewportScaleOptions = new List(); private ContextMenuButton _menuFileSaveScenes; private ContextMenuButton _menuFileReloadScenes; @@ -371,6 +418,8 @@ namespace FlaxEditor.Modules // Update window background mainWindow.BackgroundColor = Style.Current.Background; + + InitViewportScaleOptions(); InitSharedMenus(); InitMainMenu(mainWindow); @@ -392,6 +441,57 @@ namespace FlaxEditor.Modules } } + private void InitViewportScaleOptions() + { + if (DefaultViewportScaleOptions.Count == 0) + { + DefaultViewportScaleOptions.Add(new ViewportScaleOption + { + Label = "Free Aspect", + ScaleType = ViewportScaleOption.ViewportScaleType.Aspect, + Size = new Int2(1, 1), + }); + DefaultViewportScaleOptions.Add(new ViewportScaleOption + { + Label = "16:9 Aspect", + ScaleType = ViewportScaleOption.ViewportScaleType.Aspect, + Size = new Int2(16, 9), + }); + DefaultViewportScaleOptions.Add(new ViewportScaleOption + { + Label = "16:10 Aspect", + ScaleType = ViewportScaleOption.ViewportScaleType.Aspect, + Size = new Int2(16, 10), + }); + DefaultViewportScaleOptions.Add(new ViewportScaleOption + { + Label = "1920x1080 Resolution (Full HD)", + ScaleType = ViewportScaleOption.ViewportScaleType.Resolution, + Size = new Int2(1920, 1080), + }); + DefaultViewportScaleOptions.Add(new ViewportScaleOption + { + Label = "2560x1440 Resolution (2K)", + ScaleType = ViewportScaleOption.ViewportScaleType.Resolution, + Size = new Int2(2560, 1440), + }); + } + + if (Editor.Instance.ProjectCache.TryGetCustomData("CustomViewportScalingOptions", out string data)) + { + CustomViewportScaleOptions = JsonSerializer.Deserialize>(data); + } + } + + /// + /// Saves the custom viewport scaling options. + /// + public void SaveCustomViewportScalingOptions() + { + var customOptions = JsonSerializer.Serialize(CustomViewportScaleOptions); + Editor.Instance.ProjectCache.SetCustomData("CustomViewportScalingOptions", customOptions); + } + /// public override void OnUpdate() { diff --git a/Source/Editor/Viewport/PrefabWindowViewport.cs b/Source/Editor/Viewport/PrefabWindowViewport.cs index 2efe7c95f..f7c496703 100644 --- a/Source/Editor/Viewport/PrefabWindowViewport.cs +++ b/Source/Editor/Viewport/PrefabWindowViewport.cs @@ -6,6 +6,8 @@ using System.Linq; using FlaxEditor.Content; using FlaxEditor.Gizmo; using FlaxEditor.GUI.ContextMenu; +using FlaxEditor.GUI.Input; +using FlaxEditor.Modules; using FlaxEditor.SceneGraph; using FlaxEditor.Scripting; using FlaxEditor.Viewport.Cameras; @@ -13,6 +15,7 @@ using FlaxEditor.Viewport.Previews; using FlaxEditor.Windows.Assets; using FlaxEngine; using FlaxEngine.GUI; +using FlaxEngine.Json; using Utils = FlaxEditor.Utilities.Utils; namespace FlaxEditor.Viewport @@ -71,7 +74,10 @@ namespace FlaxEditor.Viewport private PrefabUIEditorRoot _uiRoot; private bool _showUI = false; + private int _defaultScaleActiveIndex = 0; + private int _customScaleActiveIndex = -1; private ContextMenuButton _uiModeButton; + private ContextMenu _uiViewCM; /// /// Event fired when the UI Mode is toggled. @@ -213,7 +219,7 @@ namespace FlaxEditor.Viewport _uiModeButton = ViewWidgetShowMenu.AddButton("UI Mode", (button) => ShowUI = button.Checked); _uiModeButton.AutoCheck = true; _uiModeButton.VisibleChanged += control => (control as ContextMenuButton).Checked = ShowUI; - + EditorGizmoViewport.AddGizmoViewportWidgets(this, TransformGizmo); // Setup input actions @@ -222,6 +228,309 @@ namespace FlaxEditor.Viewport SetUpdate(ref _update, OnUpdate); } + /// + /// Creates the view scaling options. Needs to be called after a Prefab is valid and loaded. + /// + public void CreateViewScalingOptions() + { + // View Scaling + var uiViewCM = ViewWidgetButtonMenu.AddChildMenu("UI View Scaling"); + LoadCustomUIScalingOption(); + CreateUIViewScalingContextMenu(uiViewCM.ContextMenu); + } + + private void ChangeUIView(UIModule.ViewportScaleOption uiViewScaleOption) + { + _uiRoot.SetViewSize((Float2)uiViewScaleOption.Size); + } + + private void CreateUIViewScalingContextMenu(ContextMenu vsMenu) + { + // Add default viewport sizing options + var defaultOptions = Editor.Instance.UI.DefaultViewportScaleOptions; + for (int i = 0; i < defaultOptions.Count; i++) + { + var viewportScale = defaultOptions[i]; + + // Skip aspect ratio types in prefab + if (viewportScale.ScaleType == UIModule.ViewportScaleOption.ViewportScaleType.Aspect) + continue; + + var button = vsMenu.AddButton(viewportScale.Label); + button.CloseMenuOnClick = false; + button.Tag = viewportScale; + + // No default index is active. + if (_defaultScaleActiveIndex == -1) + { + button.Icon = SpriteHandle.Invalid; + } + // This is the active index. + else if (_defaultScaleActiveIndex == i) + { + button.Icon = Style.Current.CheckBoxTick; + ChangeUIView(viewportScale); + } + + button.Clicked += () => + { + if (button.Tag == null) + return; + + // Reset selected icon on all buttons + foreach (var child in vsMenu.Items) + { + if (child is ContextMenuButton cmb && cmb.Tag is UIModule.ViewportScaleOption v) + { + if (cmb == button) + { + var index = defaultOptions.FindIndex(x => x == v); + _defaultScaleActiveIndex = index; + _customScaleActiveIndex = -1; // Reset custom index because default was chosen. + button.Icon = Style.Current.CheckBoxTick; + ChangeUIView(v); + } + else if (cmb.Icon != SpriteHandle.Invalid) + { + cmb.Icon = SpriteHandle.Invalid; + } + } + } + }; + } + if (defaultOptions.Count != 0) + vsMenu.AddSeparator(); + + // Add custom viewport options + var customOptions = Editor.Instance.UI.CustomViewportScaleOptions; + for (int i = 0; i < customOptions.Count; i++) + { + var viewportScale = customOptions[i]; + + // Skip aspect ratio types for prefabs + if (viewportScale.ScaleType == UIModule.ViewportScaleOption.ViewportScaleType.Aspect) + continue; + + var childCM = vsMenu.AddChildMenu(viewportScale.Label); + childCM.CloseMenuOnClick = false; + childCM.Tag = viewportScale; + + // No custom index is active. + if (_customScaleActiveIndex == -1) + { + childCM.Icon = SpriteHandle.Invalid; + } + // This is the active index. + else if (_customScaleActiveIndex == i) + { + childCM.Icon = Style.Current.CheckBoxTick; + ChangeUIView(viewportScale); + } + + var applyButton = childCM.ContextMenu.AddButton("Apply"); + applyButton.Tag = childCM.Tag = viewportScale; + applyButton.CloseMenuOnClick = false; + applyButton.Clicked += () => + { + if (childCM.Tag == null) + return; + + // Reset selected icon on all buttons + foreach (var child in vsMenu.Items) + { + if (child is ContextMenuButton cmb && cmb.Tag is UIModule.ViewportScaleOption v) + { + if (child == childCM) + { + var index = customOptions.FindIndex(x => x == v); + _defaultScaleActiveIndex = -1; // Reset default index because custom was chosen. + _customScaleActiveIndex = index; + childCM.Icon = Style.Current.CheckBoxTick; + ChangeUIView(v); + } + else if (cmb.Icon != SpriteHandle.Invalid) + { + cmb.Icon = SpriteHandle.Invalid; + } + } + } + }; + + var deleteButton = childCM.ContextMenu.AddButton("Delete"); + deleteButton.CloseMenuOnClick = false; + deleteButton.Clicked += () => + { + if (childCM.Tag == null) + return; + + var v = (UIModule.ViewportScaleOption)childCM.Tag; + if (childCM.Icon != SpriteHandle.Invalid) + { + _customScaleActiveIndex = -1; + _defaultScaleActiveIndex = 0; + ChangeUIView(defaultOptions[0]); + } + customOptions.Remove(v); + Editor.Instance.UI.SaveCustomViewportScalingOptions(); + vsMenu.DisposeAllItems(); + CreateUIViewScalingContextMenu(vsMenu); + vsMenu.PerformLayout(); + }; + } + if (customOptions.Count != 0) + vsMenu.AddSeparator(); + + // Add button + var add = vsMenu.AddButton("Add..."); + add.CloseMenuOnClick = false; + add.Clicked += () => + { + var popup = new ContextMenuBase + { + Size = new Float2(230, 95), + ClipChildren = false, + CullChildren = false, + }; + popup.Show(add, new Float2(add.Width, 0)); + + var nameLabel = new Label + { + Parent = popup, + AnchorPreset = AnchorPresets.TopLeft, + Text = "Name", + HorizontalAlignment = TextAlignment.Near, + }; + nameLabel.LocalX += 10; + nameLabel.LocalY += 10; + + var nameTextBox = new TextBox + { + Parent = popup, + AnchorPreset = AnchorPresets.TopLeft, + IsMultiline = false, + }; + nameTextBox.LocalX += 100; + nameTextBox.LocalY += 10; + + var whLabel = new Label + { + Parent = popup, + AnchorPreset = AnchorPresets.TopLeft, + Text = "Width & Height", + HorizontalAlignment = TextAlignment.Near, + }; + whLabel.LocalX += 10; + whLabel.LocalY += 30; + + var wValue = new IntValueBox(1920) + { + Parent = popup, + AnchorPreset = AnchorPresets.TopLeft, + MinValue = 1, + Width = 55, + }; + wValue.LocalY += 30; + wValue.LocalX += 100; + + var hValue = new IntValueBox(1080) + { + Parent = popup, + AnchorPreset = AnchorPresets.TopLeft, + MinValue = 1, + Width = 55, + }; + hValue.LocalY += 30; + hValue.LocalX += 165; + + var submitButton = new Button + { + Parent = popup, + AnchorPreset = AnchorPresets.TopLeft, + Text = "Submit", + Width = 70, + }; + submitButton.LocalX += 40; + submitButton.LocalY += 60; + + submitButton.Clicked += () => + { + var name = nameTextBox.Text + " (" + wValue.Value + "x" + hValue.Value + ")"; + + var newViewportOption = new UIModule.ViewportScaleOption + { + Label = name, + ScaleType = UIModule.ViewportScaleOption.ViewportScaleType.Resolution, + Size = new Int2(wValue.Value, hValue.Value), + }; + + customOptions.Add(newViewportOption); + Editor.Instance.UI.SaveCustomViewportScalingOptions(); + vsMenu.DisposeAllItems(); + CreateUIViewScalingContextMenu(vsMenu); + vsMenu.PerformLayout(); + }; + + var cancelButton = new Button + { + Parent = popup, + AnchorPreset = AnchorPresets.TopLeft, + Text = "Cancel", + Width = 70, + }; + cancelButton.LocalX += 120; + cancelButton.LocalY += 60; + + cancelButton.Clicked += () => + { + nameTextBox.Clear(); + hValue.Value = 9; + wValue.Value = 16; + popup.Hide(); + }; + }; + } + + /// + /// Saves the active ui scaling option. + /// + public void SaveActiveUIScalingOption() + { + var defaultKey = $"{Prefab.ID}:DefaultViewportScalingIndex"; + Editor.Instance.ProjectCache.SetCustomData(defaultKey, _defaultScaleActiveIndex.ToString()); + var customKey = $"{Prefab.ID}:CustomViewportScalingIndex"; + Editor.Instance.ProjectCache.SetCustomData(customKey, _customScaleActiveIndex.ToString()); + } + + private void LoadCustomUIScalingOption() + { + Prefab.WaitForLoaded(); + var defaultKey = $"{Prefab.ID}:DefaultViewportScalingIndex"; + if (Editor.Instance.ProjectCache.TryGetCustomData(defaultKey, out string defaultData)) + { + if (int.TryParse(defaultData, out var index)) + { + _defaultScaleActiveIndex = index; + if (index != -1) + { + ChangeUIView(Editor.Instance.UI.DefaultViewportScaleOptions[index]); + } + } + } + + var customKey = $"{Prefab.ID}:CustomViewportScalingIndex"; + if (Editor.Instance.ProjectCache.TryGetCustomData(customKey, out string data)) + { + if (int.TryParse(data, out var index)) + { + _customScaleActiveIndex = index; + if (index != -1) + { + ChangeUIView(Editor.Instance.UI.CustomViewportScaleOptions[index]); + } + } + } + } + private void OnUpdate(float deltaTime) { for (int i = 0; i < Gizmos.Count; i++) diff --git a/Source/Editor/Windows/Assets/PrefabWindow.cs b/Source/Editor/Windows/Assets/PrefabWindow.cs index 44c21d863..8202577d0 100644 --- a/Source/Editor/Windows/Assets/PrefabWindow.cs +++ b/Source/Editor/Windows/Assets/PrefabWindow.cs @@ -368,6 +368,7 @@ namespace FlaxEditor.Windows.Assets else _viewport.SetInitialUIMode(_viewport._hasUILinked); _viewport.UIModeToggled += OnUIModeToggled; + _viewport.CreateViewScalingOptions(); Graph.MainActor = _viewport.Instance; Selection.Clear(); Select(Graph.Main); @@ -564,6 +565,15 @@ namespace FlaxEditor.Windows.Assets Graph.Dispose(); } + /// + protected override void OnClose() + { + // Save current UI view size state. + _viewport.SaveActiveUIScalingOption(); + + base.OnClose(); + } + /// public EditorViewport PresenterViewport => _viewport; diff --git a/Source/Editor/Windows/GameWindow.cs b/Source/Editor/Windows/GameWindow.cs index e05f0d2db..1f5399926 100644 --- a/Source/Editor/Windows/GameWindow.cs +++ b/Source/Editor/Windows/GameWindow.cs @@ -6,6 +6,7 @@ using System.Xml; using FlaxEditor.Gizmo; using FlaxEditor.GUI.ContextMenu; using FlaxEditor.GUI.Input; +using FlaxEditor.Modules; using FlaxEditor.Options; using FlaxEngine; using FlaxEngine.GUI; @@ -34,8 +35,8 @@ namespace FlaxEditor.Windows private CursorLockMode _cursorLockMode = CursorLockMode.None; // Viewport scaling variables - private List _defaultViewportScaling = new List(); - private List _customViewportScaling = new List(); + private int _defaultScaleActiveIndex = 0; + private int _customScaleActiveIndex = -1; private float _viewportAspectRatio = 1; private float _windowAspectRatio = 1; private bool _useAspect = false; @@ -234,35 +235,6 @@ namespace FlaxEditor.Windows /// public InterfaceOptions.PlayModeFocus FocusOnPlayOption { get; set; } - private enum ViewportScaleType - { - Resolution = 0, - Aspect = 1, - } - - private class ViewportScaleOptions - { - /// - /// The name. - /// - public string Label; - - /// - /// The Type of scaling to do. - /// - public ViewportScaleType ScaleType; - - /// - /// The width and height to scale by. - /// - public Int2 Size; - - /// - /// If the scaling is active. - /// - public bool Active; - } - private class PlayModeFocusOptions { /// @@ -408,7 +380,7 @@ namespace FlaxEditor.Windows InputActions.Add(options => options.FocusConsoleCommand, () => Editor.Instance.Windows.OutputLogWin.FocusCommand()); } - private void ChangeViewportRatio(ViewportScaleOptions v) + private void ChangeViewportRatio(UIModule.ViewportScaleOption v) { if (v == null) return; @@ -427,11 +399,11 @@ namespace FlaxEditor.Windows { switch (v.ScaleType) { - case ViewportScaleType.Aspect: + case UIModule.ViewportScaleOption.ViewportScaleType.Aspect: _useAspect = true; _freeAspect = false; break; - case ViewportScaleType.Resolution: + case UIModule.ViewportScaleOption.ViewportScaleType.Resolution: _useAspect = false; _freeAspect = false; break; @@ -629,45 +601,6 @@ namespace FlaxEditor.Windows // Viewport aspect ratio { // Create default scaling options if they dont exist from deserialization. - if (_defaultViewportScaling.Count == 0) - { - _defaultViewportScaling.Add(new ViewportScaleOptions - { - Label = "Free Aspect", - ScaleType = ViewportScaleType.Aspect, - Size = new Int2(1, 1), - Active = true, - }); - _defaultViewportScaling.Add(new ViewportScaleOptions - { - Label = "16:9 Aspect", - ScaleType = ViewportScaleType.Aspect, - Size = new Int2(16, 9), - Active = false, - }); - _defaultViewportScaling.Add(new ViewportScaleOptions - { - Label = "16:10 Aspect", - ScaleType = ViewportScaleType.Aspect, - Size = new Int2(16, 10), - Active = false, - }); - _defaultViewportScaling.Add(new ViewportScaleOptions - { - Label = "1920x1080 Resolution (Full HD)", - ScaleType = ViewportScaleType.Resolution, - Size = new Int2(1920, 1080), - Active = false, - }); - _defaultViewportScaling.Add(new ViewportScaleOptions - { - Label = "2560x1440 Resolution (2K)", - ScaleType = ViewportScaleType.Resolution, - Size = new Int2(2560, 1440), - Active = false, - }); - } - var vsMenu = menu.AddChildMenu("Viewport Size").ContextMenu; CreateViewportSizingContextMenu(vsMenu); @@ -771,15 +704,25 @@ namespace FlaxEditor.Windows private void CreateViewportSizingContextMenu(ContextMenu vsMenu) { // Add default viewport sizing options - for (int i = 0; i < _defaultViewportScaling.Count; i++) + var defaultOptions = Editor.UI.DefaultViewportScaleOptions; + for (int i = 0; i < defaultOptions.Count; i++) { - var viewportScale = _defaultViewportScaling[i]; + var viewportScale = defaultOptions[i]; var button = vsMenu.AddButton(viewportScale.Label); button.CloseMenuOnClick = false; - button.Icon = viewportScale.Active ? Style.Current.CheckBoxTick : SpriteHandle.Invalid; button.Tag = viewportScale; - if (viewportScale.Active) + + // No default index is active. + if (_defaultScaleActiveIndex == -1) + { + button.Icon = SpriteHandle.Invalid; + } + // This is the active index. + else if (_defaultScaleActiveIndex == i) + { + button.Icon = Style.Current.CheckBoxTick; ChangeViewportRatio(viewportScale); + } button.Clicked += () => { @@ -789,36 +732,47 @@ namespace FlaxEditor.Windows // Reset selected icon on all buttons foreach (var child in vsMenu.Items) { - if (child is ContextMenuButton cmb && cmb.Tag is ViewportScaleOptions v) + if (child is ContextMenuButton cmb && cmb.Tag is UIModule.ViewportScaleOption v) { if (cmb == button) { - v.Active = true; + var index = defaultOptions.FindIndex(x => x == v); + _defaultScaleActiveIndex = index; + _customScaleActiveIndex = -1; // Reset custom index because default was chosen. button.Icon = Style.Current.CheckBoxTick; ChangeViewportRatio(v); } - else if (v.Active) + else if (cmb.Icon != SpriteHandle.Invalid) { cmb.Icon = SpriteHandle.Invalid; - v.Active = false; } } } }; } - if (_defaultViewportScaling.Count != 0) + if (defaultOptions.Count != 0) vsMenu.AddSeparator(); // Add custom viewport options - for (int i = 0; i < _customViewportScaling.Count; i++) + var customOptions = Editor.UI.CustomViewportScaleOptions; + for (int i = 0; i < customOptions.Count; i++) { - var viewportScale = _customViewportScaling[i]; + var viewportScale = customOptions[i]; var childCM = vsMenu.AddChildMenu(viewportScale.Label); childCM.CloseMenuOnClick = false; - childCM.Icon = viewportScale.Active ? Style.Current.CheckBoxTick : SpriteHandle.Invalid; childCM.Tag = viewportScale; - if (viewportScale.Active) + + // No custom index is active. + if (_customScaleActiveIndex == -1) + { + childCM.Icon = SpriteHandle.Invalid; + } + // This is the active index. + else if (_customScaleActiveIndex == i) + { + childCM.Icon = Style.Current.CheckBoxTick; ChangeViewportRatio(viewportScale); + } var applyButton = childCM.ContextMenu.AddButton("Apply"); applyButton.Tag = childCM.Tag = viewportScale; @@ -831,18 +785,19 @@ namespace FlaxEditor.Windows // Reset selected icon on all buttons foreach (var child in vsMenu.Items) { - if (child is ContextMenuButton cmb && cmb.Tag is ViewportScaleOptions v) + if (child is ContextMenuButton cmb && cmb.Tag is UIModule.ViewportScaleOption v) { if (child == childCM) { - v.Active = true; + var index = customOptions.FindIndex(x => x == v); + _defaultScaleActiveIndex = -1; // Reset default index because custom was chosen. + _customScaleActiveIndex = index; childCM.Icon = Style.Current.CheckBoxTick; ChangeViewportRatio(v); } - else if (v.Active) + else if (cmb.Icon != SpriteHandle.Invalid) { cmb.Icon = SpriteHandle.Invalid; - v.Active = false; } } } @@ -855,20 +810,21 @@ namespace FlaxEditor.Windows if (childCM.Tag == null) return; - var v = (ViewportScaleOptions)childCM.Tag; - if (v.Active) + var v = (UIModule.ViewportScaleOption)childCM.Tag; + if (childCM.Icon != SpriteHandle.Invalid) { - v.Active = false; - _defaultViewportScaling[0].Active = true; - ChangeViewportRatio(_defaultViewportScaling[0]); + _customScaleActiveIndex = -1; + _defaultScaleActiveIndex = 0; + ChangeViewportRatio(defaultOptions[0]); } - _customViewportScaling.Remove(v); + customOptions.Remove(v); + Editor.UI.SaveCustomViewportScalingOptions(); vsMenu.DisposeAllItems(); CreateViewportSizingContextMenu(vsMenu); vsMenu.PerformLayout(); }; } - if (_customViewportScaling.Count != 0) + if (customOptions.Count != 0) vsMenu.AddSeparator(); // Add button @@ -966,19 +922,20 @@ namespace FlaxEditor.Windows submitButton.Clicked += () => { - Enum.TryParse(typeDropdown.SelectedItem, out ViewportScaleType type); + Enum.TryParse(typeDropdown.SelectedItem, out UIModule.ViewportScaleOption.ViewportScaleType type); - var combineString = type == ViewportScaleType.Aspect ? ":" : "x"; + var combineString = type == UIModule.ViewportScaleOption.ViewportScaleType.Aspect ? ":" : "x"; var name = nameTextBox.Text + " (" + wValue.Value + combineString + hValue.Value + ") " + typeDropdown.SelectedItem; - var newViewportOption = new ViewportScaleOptions + var newViewportOption = new UIModule.ViewportScaleOption { ScaleType = type, Label = name, Size = new Int2(wValue.Value, hValue.Value), }; - _customViewportScaling.Add(newViewportOption); + customOptions.Add(newViewportOption); + Editor.UI.SaveCustomViewportScalingOptions(); vsMenu.DisposeAllItems(); CreateViewportSizingContextMenu(vsMenu); vsMenu.PerformLayout(); @@ -1221,8 +1178,8 @@ namespace FlaxEditor.Windows writer.WriteAttributeString("ShowGUI", ShowGUI.ToString()); writer.WriteAttributeString("EditGUI", EditGUI.ToString()); writer.WriteAttributeString("ShowDebugDraw", ShowDebugDraw.ToString()); - writer.WriteAttributeString("DefaultViewportScaling", JsonSerializer.Serialize(_defaultViewportScaling)); - writer.WriteAttributeString("CustomViewportScaling", JsonSerializer.Serialize(_customViewportScaling)); + writer.WriteAttributeString("DefaultViewportScalingIndex", _defaultScaleActiveIndex.ToString()); + writer.WriteAttributeString("CustomViewportScalingIndex", _customScaleActiveIndex.ToString()); } /// @@ -1234,22 +1191,21 @@ namespace FlaxEditor.Windows EditGUI = value1; if (bool.TryParse(node.GetAttribute("ShowDebugDraw"), out value1)) ShowDebugDraw = value1; - if (node.HasAttribute("CustomViewportScaling")) - _customViewportScaling = JsonSerializer.Deserialize>(node.GetAttribute("CustomViewportScaling")); + if (int.TryParse(node.GetAttribute("DefaultViewportScalingIndex"), out int value2)) + _defaultScaleActiveIndex = value2; + if (int.TryParse(node.GetAttribute("CustomViewportScalingIndex"), out value2)) + _customScaleActiveIndex = value2; - for (int i = 0; i < _customViewportScaling.Count; i++) + if (_defaultScaleActiveIndex != -1) { - if (_customViewportScaling[i].Active) - ChangeViewportRatio(_customViewportScaling[i]); + var options = Editor.UI.DefaultViewportScaleOptions; + ChangeViewportRatio(options[_defaultScaleActiveIndex]); } - - if (node.HasAttribute("DefaultViewportScaling")) - _defaultViewportScaling = JsonSerializer.Deserialize>(node.GetAttribute("DefaultViewportScaling")); - - for (int i = 0; i < _defaultViewportScaling.Count; i++) + + if (_customScaleActiveIndex != -1) { - if (_defaultViewportScaling[i].Active) - ChangeViewportRatio(_defaultViewportScaling[i]); + var options = Editor.UI.CustomViewportScaleOptions; + ChangeViewportRatio(options[_customScaleActiveIndex]); } }