From c5e558172d0cb295b6b925a8cbe794d8029e5c60 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Thu, 22 Dec 2022 11:40:10 -0600 Subject: [PATCH] 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; ///