diff --git a/Source/Editor/Editor.cs b/Source/Editor/Editor.cs
index 13b748d94..0b85fbdad 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..28f9577d8
--- /dev/null
+++ b/Source/Editor/GUI/Popups/AutoSavePopup.cs
@@ -0,0 +1,169 @@
+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 _timeLabel;
+ private Button _saveNowButton;
+ private Button _cancelSaveButton;
+ private Color _defaultTextColor;
+ private bool _isMoved = false;
+
+ ///
+ /// 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,
+ BackgroundColor = Color.Transparent,
+ };
+
+ _timeLabel = new Label(0, 0, 25, 10)
+ {
+ Parent = _backgroundPanel,
+ Text = _timeRemaining.ToString(),
+ HorizontalAlignment = TextAlignment.Near,
+ VerticalAlignment = TextAlignment.Near,
+ AutoWidth = true,
+ Height = 14,
+ AnchorPreset = AnchorPresets.MiddleLeft,
+ };
+
+ _saveNowButton = new Button
+ {
+ Parent = _backgroundPanel,
+ Height = 14,
+ Width = 60,
+ 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 the auto save timer."
+ };
+ _saveNowButton.LocalX -= 85;
+
+ _cancelSaveButton = new Button
+ {
+ Parent = _backgroundPanel,
+ Height = 14,
+ Width = 70,
+ AnchorPreset = AnchorPresets.MiddleRight,
+ BackgroundColor = Color.Transparent,
+ BorderColor = Color.Transparent,
+ BackgroundColorHighlighted = Color.Transparent,
+ BackgroundColorSelected = Color.Transparent,
+ BorderColorHighlighted = Color.Transparent,
+ Text = "Cancel Save",
+ TooltipText = "Cancels this auto save."
+ };
+ _cancelSaveButton.LocalX -= 5;
+
+ _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 = "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;
+ }
+ }
+
+ ///
+ 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);
+ }
+
+ ///
+ /// 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 = Editor.Instance.UI.StatusBar.Height,
+ Width = 250,
+ AnchorPreset = AnchorPresets.BottomRight,
+ };
+ 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 814e80d0a..b02af39cf 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;
///