From c5e558172d0cb295b6b925a8cbe794d8029e5c60 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Thu, 22 Dec 2022 11:40:10 -0600 Subject: [PATCH 1/2] Added auto save reminder popup with an option to change the reminder time. --- Source/Editor/Editor.cs | 31 ++- Source/Editor/GUI/Popups/AutoSavePopup.cs | 224 ++++++++++++++++++++++ Source/Editor/Options/GeneralOptions.cs | 11 +- 3 files changed, 263 insertions(+), 3 deletions(-) create mode 100644 Source/Editor/GUI/Popups/AutoSavePopup.cs diff --git a/Source/Editor/Editor.cs b/Source/Editor/Editor.cs index 94cbf4ce1..cac61704c 100644 --- a/Source/Editor/Editor.cs +++ b/Source/Editor/Editor.cs @@ -9,6 +9,7 @@ using FlaxEditor.Content; using FlaxEditor.Content.Import; using FlaxEditor.Content.Settings; using FlaxEditor.Content.Thumbnails; +using FlaxEditor.GUI; using FlaxEditor.Modules; using FlaxEditor.Modules.SourceCodeEditing; using FlaxEditor.Options; @@ -46,6 +47,8 @@ namespace FlaxEditor private bool _isAfterInit, _areModulesInited, _areModulesAfterInitEnd, _isHeadlessMode; private string _projectToOpen; private float _lastAutoSaveTimer; + private AutoSavePopup _autoSavePopup; + private bool _autoSaveNow; private Guid _startupSceneCmdLine; private const string ProjectDataLastScene = "LastScene"; @@ -491,7 +494,28 @@ namespace FlaxEditor var timeToNextSave = options.AutoSaveFrequency * 60.0f - timeSinceLastSave; var countDownDuration = 4.0f; - if (timeToNextSave <= 0.0f) + // Show auto save popup + if (timeToNextSave <= options.AutoSaveReminderTime && timeToNextSave >= 0) + { + if (_autoSavePopup == null) + { + _autoSavePopup = AutoSavePopup.Show(Instance.Windows.MainWindow.GUI, timeToNextSave); + _autoSavePopup.SaveNowButton.Clicked += () => _autoSaveNow = true; + _autoSavePopup.CancelSaveButton.Clicked += () => + { + Log("Auto save canceled"); + _autoSavePopup.HidePopup(); + _lastAutoSaveTimer = Time.UnscaledGameTime; // Reset timer + }; + } + else if (!_autoSavePopup.Visible && !_autoSavePopup.UserClosed) + _autoSavePopup.ShowPopup(); + + if (_autoSavePopup.Visible) + _autoSavePopup.UpdateTime(timeToNextSave); + } + + if (timeToNextSave <= 0.0f || _autoSaveNow) { Log("Auto save"); _lastAutoSaveTimer = Time.UnscaledGameTime; @@ -499,6 +523,11 @@ namespace FlaxEditor Scene.SaveScenes(); if (options.AutoSaveContent) SaveContent(); + + // Hide auto save popup and reset user closed + _autoSavePopup.HidePopup(); + _autoSavePopup.UserClosed = false; + _autoSaveNow = false; } else if (timeToNextSave < countDownDuration) { diff --git a/Source/Editor/GUI/Popups/AutoSavePopup.cs b/Source/Editor/GUI/Popups/AutoSavePopup.cs new file mode 100644 index 000000000..bb337059d --- /dev/null +++ b/Source/Editor/GUI/Popups/AutoSavePopup.cs @@ -0,0 +1,224 @@ +using FlaxEngine; +using FlaxEngine.GUI; + +namespace FlaxEditor.GUI +{ + /// + /// Popup menu for reminding of an upcoming auto save. + /// + public class AutoSavePopup : ContainerControl + { + /// + /// Gets or sets the value for if the user has manually closed this popup. + /// + public bool UserClosed { get; set; } + + /// + /// The save now button. Used to skip the last remaining auto save time. + /// + public Button SaveNowButton => _saveNowButton; + + /// + /// Button that should be used to cancel the auto save. + /// + public Button CancelSaveButton => _cancelSaveButton; + + private int _timeRemaining; + private Panel _backgroundPanel; + private Label _autoSaveLabel; + private Label _timeRemainingLabel; + private Label _timeLabel; + private Button _saveNowButton; + private Button _cancelSaveButton; + private Button _closeMenuButton; + private Color _defaultTextColor; + + /// + /// Initialize the AutoSavePopup. + /// + /// The initial time to set the time label to. + public AutoSavePopup(float initialTime) + { + UpdateTime(initialTime); + + _backgroundPanel = new Panel(ScrollBars.None) + { + Parent = this, + AnchorPreset = AnchorPresets.StretchAll, + }; + + _autoSaveLabel = new Label(0, 0, 25, 10) + { + Parent = _backgroundPanel, + Text = "Auto Save", + AutoWidth = true, + AutoHeight = true, + AnchorPreset = AnchorPresets.TopLeft, + }; + _autoSaveLabel.Font.Size = 16; + _autoSaveLabel.LocalX += 5; + _autoSaveLabel.LocalY += 5; + + _timeRemainingLabel = new Label(0, 0, 25, 10) + { + Parent = _backgroundPanel, + Text = "Time Remaining: ", + AutoWidth = true, + AutoHeight = true, + AnchorPreset = AnchorPresets.MiddleLeft, + }; + _timeRemainingLabel.Font.Size = 16; + _timeRemainingLabel.LocalX += 5; + _timeRemainingLabel.LocalY -= _timeRemainingLabel.Height / 2; + + _timeLabel = new Label(0, 0, 25, 10) + { + Parent = _backgroundPanel, + Text = _timeRemaining.ToString(), + HorizontalAlignment = TextAlignment.Far, + VerticalAlignment = TextAlignment.Center, + Width = 25, + AutoHeight = true, + AnchorPreset = AnchorPresets.MiddleRight, + }; + _timeLabel.Font.Size = 16; + _timeLabel.LocalX -= 5; + _timeLabel.LocalY -= _timeLabel.Height / 2; + + _saveNowButton = new Button + { + Parent = _backgroundPanel, + Height = 14, + Width = 60, + AnchorPreset = AnchorPresets.BottomLeft, + BackgroundColor = Color.Transparent, + BorderColor = Color.Transparent, + BackgroundColorHighlighted = Color.Transparent, + BackgroundColorSelected = Color.Transparent, + BorderColorHighlighted = Color.Transparent, + Text = "Save Now", + TooltipText = "Saves now and restarts auto save timer." + }; + _saveNowButton.LocalY -= 5; + _saveNowButton.LocalX += 5; + + _cancelSaveButton = new Button + { + Parent = _backgroundPanel, + Height = 14, + Width = 70, + AnchorPreset = AnchorPresets.BottomRight, + BackgroundColor = Color.Transparent, + BorderColor = Color.Transparent, + BackgroundColorHighlighted = Color.Transparent, + BackgroundColorSelected = Color.Transparent, + BorderColorHighlighted = Color.Transparent, + Text = "Cancel Save", + TooltipText = "Cancels this auto save." + }; + _cancelSaveButton.LocalY -= 5; + _cancelSaveButton.LocalX -= 5; + + _closeMenuButton = new Button + { + Parent = _backgroundPanel, + Height = 14, + Width = 14, + AnchorPreset = AnchorPresets.TopRight, + BackgroundBrush = new SpriteBrush(Style.Current.Cross), + BorderColor = Color.Transparent, + BackgroundColorHighlighted = Style.Current.ForegroundGrey, + BackgroundColorSelected = Color.Transparent, + BorderColorHighlighted = Color.Transparent, + BorderColorSelected = Color.Transparent, + TooltipText = "Close Popup." + }; + _closeMenuButton.LocalY += 5; + _closeMenuButton.LocalX -= 5; + _closeMenuButton.BackgroundColor = _closeMenuButton.TextColor; + _closeMenuButton.Clicked += () => + { + UserClosed = true; + HidePopup(); + }; + + _defaultTextColor = _saveNowButton.TextColor; + } + + /// + /// Updates the time label + /// + /// The time to change the label to. + public void UpdateTime(float time) + { + _timeRemaining = Mathf.CeilToInt(time); + if (_timeLabel != null) + _timeLabel.Text = _timeRemaining.ToString(); + } + + /// + public override void Update(float deltaTime) + { + if (IsMouseOver) + { + _saveNowButton.TextColor = _saveNowButton.IsMouseOver ? Style.Current.BackgroundHighlighted : _defaultTextColor; + _cancelSaveButton.TextColor = _cancelSaveButton.IsMouseOver ? Style.Current.BackgroundHighlighted : _defaultTextColor; + } + base.Update(deltaTime); + } + + /// + public override void Draw() + { + // Draw background + var style = Style.Current; + var bounds = new Rectangle(Float2.Zero, Size); + Render2D.FillRectangle(bounds, style.Background); + Render2D.DrawRectangle(bounds, Color.Lerp(style.BackgroundSelected, style.Background, 0.6f)); + + base.Draw(); + } + + /// + /// Creates and shows the AutoSavePopup + /// + /// The parent control. + /// The time to start at. + /// + public static AutoSavePopup Show(ContainerControl parentControl, float initialTime) + { + var popup = new AutoSavePopup(initialTime) + { + Parent = parentControl, + Height = 75, + Width = 250, + AnchorPreset = AnchorPresets.BottomRight, + }; + popup.LocalX -= 10; + popup.LocalY -= 30; + popup.ShowPopup(); + return popup; + } + + /// + /// Shows the popup by changing its visibility + /// + public void ShowPopup() + { + Visible = true; + UserClosed = false; + _saveNowButton.TextColor = _defaultTextColor; + _cancelSaveButton.TextColor = _defaultTextColor; + } + + /// + /// Hides the popup by changing its visibility + /// + public void HidePopup() + { + Visible = false; + if (_containsFocus) + Defocus(); + } + } +} diff --git a/Source/Editor/Options/GeneralOptions.cs b/Source/Editor/Options/GeneralOptions.cs index 5f05cae2c..d1f168444 100644 --- a/Source/Editor/Options/GeneralOptions.cs +++ b/Source/Editor/Options/GeneralOptions.cs @@ -189,19 +189,26 @@ namespace FlaxEditor.Options [DefaultValue(5), Limit(1)] [EditorDisplay("Auto Save", "Auto Save Frequency"), EditorOrder(801), Tooltip("The interval between auto saves (in minutes)")] public int AutoSaveFrequency { get; set; } = 5; + + /// + /// Gets or sets a value indicating the time before the auto save that the popup shows (in seconds). + /// + [DefaultValue(10), Limit(-1)] + [EditorDisplay("Auto Save", "Auto Save Reminder Time"), EditorOrder(802), Tooltip("The time before the auto save that the reminder popup shows (in seconds). Set to -1 to not show the reminder popup.")] + public int AutoSaveReminderTime { get; set; } = 10; /// /// Gets or sets a value indicating whether enable auto saves for scenes. /// [DefaultValue(true)] - [EditorDisplay("Auto Save", "Auto Save Scenes"), EditorOrder(802), Tooltip("Enables or disables auto saving opened scenes")] + [EditorDisplay("Auto Save", "Auto Save Scenes"), EditorOrder(803), Tooltip("Enables or disables auto saving opened scenes")] public bool AutoSaveScenes { get; set; } = true; /// /// Gets or sets a value indicating whether enable auto saves for content. /// [DefaultValue(true)] - [EditorDisplay("Auto Save", "Auto Save Content"), EditorOrder(803), Tooltip("Enables or disables auto saving content")] + [EditorDisplay("Auto Save", "Auto Save Content"), EditorOrder(804), Tooltip("Enables or disables auto saving content")] public bool AutoSaveContent { get; set; } = true; /// From 8c78493a51b3ea428ea04159b6dce5eea9119c61 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Tue, 27 Dec 2022 10:08:08 -0600 Subject: [PATCH 2/2] Simplified auto save poprup and moved it to be on the status bar for better UX. --- Source/Editor/GUI/Popups/AutoSavePopup.cs | 105 ++++++---------------- 1 file changed, 25 insertions(+), 80 deletions(-) diff --git a/Source/Editor/GUI/Popups/AutoSavePopup.cs b/Source/Editor/GUI/Popups/AutoSavePopup.cs index bb337059d..28f9577d8 100644 --- a/Source/Editor/GUI/Popups/AutoSavePopup.cs +++ b/Source/Editor/GUI/Popups/AutoSavePopup.cs @@ -25,13 +25,11 @@ namespace FlaxEditor.GUI private int _timeRemaining; private Panel _backgroundPanel; - private Label _autoSaveLabel; - private Label _timeRemainingLabel; private Label _timeLabel; private Button _saveNowButton; private Button _cancelSaveButton; - private Button _closeMenuButton; private Color _defaultTextColor; + private bool _isMoved = false; /// /// Initialize the AutoSavePopup. @@ -45,69 +43,42 @@ namespace FlaxEditor.GUI { Parent = this, AnchorPreset = AnchorPresets.StretchAll, + BackgroundColor = Color.Transparent, }; - _autoSaveLabel = new Label(0, 0, 25, 10) - { - Parent = _backgroundPanel, - Text = "Auto Save", - AutoWidth = true, - AutoHeight = true, - AnchorPreset = AnchorPresets.TopLeft, - }; - _autoSaveLabel.Font.Size = 16; - _autoSaveLabel.LocalX += 5; - _autoSaveLabel.LocalY += 5; - - _timeRemainingLabel = new Label(0, 0, 25, 10) - { - Parent = _backgroundPanel, - Text = "Time Remaining: ", - AutoWidth = true, - AutoHeight = true, - AnchorPreset = AnchorPresets.MiddleLeft, - }; - _timeRemainingLabel.Font.Size = 16; - _timeRemainingLabel.LocalX += 5; - _timeRemainingLabel.LocalY -= _timeRemainingLabel.Height / 2; - _timeLabel = new Label(0, 0, 25, 10) { Parent = _backgroundPanel, Text = _timeRemaining.ToString(), - HorizontalAlignment = TextAlignment.Far, - VerticalAlignment = TextAlignment.Center, - Width = 25, - AutoHeight = true, - AnchorPreset = AnchorPresets.MiddleRight, + HorizontalAlignment = TextAlignment.Near, + VerticalAlignment = TextAlignment.Near, + AutoWidth = true, + Height = 14, + AnchorPreset = AnchorPresets.MiddleLeft, }; - _timeLabel.Font.Size = 16; - _timeLabel.LocalX -= 5; - _timeLabel.LocalY -= _timeLabel.Height / 2; _saveNowButton = new Button { Parent = _backgroundPanel, Height = 14, Width = 60, - AnchorPreset = AnchorPresets.BottomLeft, + AnchorPreset = AnchorPresets.MiddleRight, BackgroundColor = Color.Transparent, BorderColor = Color.Transparent, BackgroundColorHighlighted = Color.Transparent, BackgroundColorSelected = Color.Transparent, BorderColorHighlighted = Color.Transparent, Text = "Save Now", - TooltipText = "Saves now and restarts auto save timer." + TooltipText = "Saves now and restarts the auto save timer." }; - _saveNowButton.LocalY -= 5; - _saveNowButton.LocalX += 5; + _saveNowButton.LocalX -= 85; _cancelSaveButton = new Button { Parent = _backgroundPanel, Height = 14, Width = 70, - AnchorPreset = AnchorPresets.BottomRight, + AnchorPreset = AnchorPresets.MiddleRight, BackgroundColor = Color.Transparent, BorderColor = Color.Transparent, BackgroundColorHighlighted = Color.Transparent, @@ -116,32 +87,8 @@ namespace FlaxEditor.GUI Text = "Cancel Save", TooltipText = "Cancels this auto save." }; - _cancelSaveButton.LocalY -= 5; _cancelSaveButton.LocalX -= 5; - _closeMenuButton = new Button - { - Parent = _backgroundPanel, - Height = 14, - Width = 14, - AnchorPreset = AnchorPresets.TopRight, - BackgroundBrush = new SpriteBrush(Style.Current.Cross), - BorderColor = Color.Transparent, - BackgroundColorHighlighted = Style.Current.ForegroundGrey, - BackgroundColorSelected = Color.Transparent, - BorderColorHighlighted = Color.Transparent, - BorderColorSelected = Color.Transparent, - TooltipText = "Close Popup." - }; - _closeMenuButton.LocalY += 5; - _closeMenuButton.LocalX -= 5; - _closeMenuButton.BackgroundColor = _closeMenuButton.TextColor; - _closeMenuButton.Clicked += () => - { - UserClosed = true; - HidePopup(); - }; - _defaultTextColor = _saveNowButton.TextColor; } @@ -153,7 +100,19 @@ namespace FlaxEditor.GUI { _timeRemaining = Mathf.CeilToInt(time); if (_timeLabel != null) - _timeLabel.Text = _timeRemaining.ToString(); + _timeLabel.Text = "Auto Save in: " + _timeRemaining; + + // Move on text update if the progress bar is visible - removes this call from update + if (Editor.Instance.UI.ProgressVisible && !_isMoved) + { + _isMoved = true; + LocalX -= 250; + } + else if (!Editor.Instance.UI.ProgressVisible && _isMoved) + { + LocalX += 250; + _isMoved = false; + } } /// @@ -167,18 +126,6 @@ namespace FlaxEditor.GUI base.Update(deltaTime); } - /// - public override void Draw() - { - // Draw background - var style = Style.Current; - var bounds = new Rectangle(Float2.Zero, Size); - Render2D.FillRectangle(bounds, style.Background); - Render2D.DrawRectangle(bounds, Color.Lerp(style.BackgroundSelected, style.Background, 0.6f)); - - base.Draw(); - } - /// /// Creates and shows the AutoSavePopup /// @@ -190,12 +137,10 @@ namespace FlaxEditor.GUI var popup = new AutoSavePopup(initialTime) { Parent = parentControl, - Height = 75, + Height = Editor.Instance.UI.StatusBar.Height, Width = 250, AnchorPreset = AnchorPresets.BottomRight, }; - popup.LocalX -= 10; - popup.LocalY -= 30; popup.ShowPopup(); return popup; }