Skip to content

Commit f19a719

Browse files
authored
Save/Save As tweaks (#3495)
* Fix default %project%/Assets/ location when saving prefabs + scenes * Display error message box if it's not a valid assets location * Tweak "File > Save" enabled conditions to match if they'll do something
1 parent cd82c81 commit f19a719

File tree

2 files changed

+31
-41
lines changed

2 files changed

+31
-41
lines changed

engine/Sandbox.Tools/Editor/EditorMainWindow.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ public void ShowCloseDialog()
101101

102102
private Option save;
103103
private Option saveAs;
104+
private Option saveAll;
104105
private Option discard;
105106
private Option undoOption;
106107
private Option redoOption;
@@ -124,7 +125,7 @@ internal EditorMainWindow()
124125
FileMenu.AddSeparator();
125126
save = FileMenu.AddOption( "Save", "save", EditorScene.SaveSession, "editor.save" );
126127
saveAs = FileMenu.AddOption( "Save As..", "save_as", EditorScene.SaveSessionAs, "editor.save-as" );
127-
FileMenu.AddOption( "Save All", null, EditorScene.SaveAllSessions, "editor.save-all" );
128+
saveAll = FileMenu.AddOption( "Save All", null, EditorScene.SaveAllSessions, "editor.save-all" );
128129
discard = FileMenu.AddOption( "Discard Changes", "auto_delete", EditorScene.Discard );
129130
FileMenu.AddSeparator();
130131
FileMenu.AddOption( "Close Project", "disabled_by_default", () => { showLauncherOnExit = true; Quit(); } );
@@ -488,8 +489,9 @@ public void SetVisible( bool visible )
488489

489490
private void OnFileMenuAboutToShow()
490491
{
491-
save.Enabled = SceneEditorSession.Active?.HasUnsavedChanges ?? true;
492-
saveAs.Enabled = SceneEditorSession.Active?.HasUnsavedChanges ?? true;
492+
save.Enabled = SceneEditorSession.Active?.HasUnsavedChanges ?? false;
493+
saveAs.Enabled = SceneEditorSession.Active is not null;
494+
saveAll.Enabled = SceneEditorSession.All.Any();
493495
discard.Enabled = SceneEditorSession.Active?.HasUnsavedChanges ?? false;
494496
}
495497

engine/Sandbox.Tools/Scene/Session/SceneEditorSession.cs

Lines changed: 26 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using Facepunch.ActionGraphs;
22
using Sandbox.ActionGraphs;
33
using System;
4+
using System.IO;
45

56
namespace Editor;
67

@@ -305,62 +306,49 @@ public void Reload()
305306
public void Save( bool saveAs )
306307
{
307308
bool isPrefab = Scene is PrefabScene;
308-
var saveLocation = string.Empty;
309+
string extension = isPrefab ? "prefab" : "scene";
310+
string fileType = isPrefab ? "Prefab" : "Scene";
309311

310-
if ( Scene.Source is not null && AssetSystem.FindByPath( Scene.Source.ResourcePath ) is Asset sourceAsset )
312+
var saveLocation = string.Empty;
313+
if ( !saveAs && Scene.Source is not null && AssetSystem.FindByPath( Scene.Source.ResourcePath ) is Asset sourceAsset )
311314
{
312315
saveLocation = sourceAsset.AbsolutePath;
313316
}
314317
else
315318
{
316-
saveAs = true;
317-
}
318-
319-
string extension = isPrefab ? "prefab" : "scene";
320-
string fileType = isPrefab ? "Prefab" : "Scene";
321-
322-
if ( saveAs )
323-
{
324-
if ( string.IsNullOrEmpty( saveLocation ) )
319+
saveLocation = ProjectCookie.GetString( $"LastSaveLocation.{extension}", string.Empty );
320+
if ( !Directory.Exists( saveLocation ) )
325321
{
326-
saveLocation = System.IO.Path.Combine(
327-
System.IO.Path.GetDirectoryName( ProjectCookie.GetString( $"LastSaveLocation.{extension}", Project.Current.GetAssetsPath() ) ),
328-
$"untitled.{extension}" );
322+
saveLocation = Project.Current.GetAssetsPath();
329323
}
330324

331-
saveLocation = EditorUtility.SaveFileDialog( $"Save {fileType} As..", extension, saveLocation );
332-
325+
saveLocation = EditorUtility.SaveFileDialog( $"Save {fileType} As..", extension,
326+
Path.Combine( saveLocation, $"untitled.{extension}" ) );
333327
if ( saveLocation is null )
334328
return;
335329

336-
ProjectCookie.SetString( $"LastSaveLocation.{extension}", System.IO.Path.GetDirectoryName( saveLocation ) );
337-
}
330+
if ( !saveLocation.NormalizeFilename( false ).StartsWith( Project.Current.GetAssetsPath().NormalizeFilename( false ) ) )
331+
{
332+
// enforce saving inside Assets/ - if it's outside, complain and let them retry
333+
EditorUtility.DisplayDialog( $"Save Failed: Invalid location",
334+
$"{fileType}s must be saved inside the Assets folder of your project", "Cancel", "Retry",
335+
() => Save( true ) );
336+
return;
337+
}
338338

339-
EditorEvent.Run( "scene.beforesave", SceneEditorSession.Active.Scene );
339+
ProjectCookie.SetString( $"LastSaveLocation.{extension}", Path.GetDirectoryName( saveLocation ) );
340+
}
340341

341-
if ( Scene is PrefabScene prefabScene )
342-
{
343-
var prefabFile = prefabScene.ToPrefabFile();
344-
var asset = AssetSystem.CreateResource( "prefab", saveLocation );
345-
asset.SaveToDisk( prefabFile );
342+
EditorEvent.Run( "scene.beforesave", Active.Scene );
346343

347-
// Update this scene's path
348-
Scene.Source = prefabFile;
349-
Scene.Name = System.IO.Path.GetFileNameWithoutExtension( saveLocation );
350-
}
351-
else
352-
{
353-
var sceneFile = Scene.CreateSceneFile();
354-
var asset = AssetSystem.CreateResource( "scene", saveLocation );
355-
asset.SaveToDisk( sceneFile );
344+
var asset = AssetSystem.CreateResource( extension, saveLocation );
345+
Assert.NotNull( asset, $"Failed to CreateResource for {fileType} at {saveLocation}" );
356346

357-
// Update this scene's path
358-
Scene.Source = sceneFile;
359-
Scene.Name = System.IO.Path.GetFileNameWithoutExtension( saveLocation );
360-
}
347+
GameResource resource = Scene is PrefabScene prefabScene ? prefabScene.ToPrefabFile() : Scene.CreateSceneFile();
348+
asset.SaveToDisk( resource );
361349

362350
HasUnsavedChanges = false;
363-
EditorEvent.Run( "scene.saved", SceneEditorSession.Active.Scene );
351+
EditorEvent.Run( "scene.saved", Active.Scene );
364352

365353
UpdateEditorTitle();
366354
}

0 commit comments

Comments
 (0)