Skip to content

Commit 5540d89

Browse files
committed
fixup! feat: Implement Project selection/creation
1 parent 38088d4 commit 5540d89

File tree

9 files changed

+193
-14
lines changed

9 files changed

+193
-14
lines changed
Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,23 @@
1+
using Stride.Core.Assets.Editor.Services;
12
using Stride.Core.Presentation.Commands;
23
using Stride.Core.Presentation.ViewModels;
34

45
namespace Stride.Core.Assets.Editor.Avalonia;
56

67
public class NewOrOpenSessionTemplateCollectionViewModel
78
{
9+
private readonly IViewModelServiceProvider serviceProvider;
810
public NewOrOpenSessionTemplateCollectionViewModel(IViewModelServiceProvider serviceProvider)
9-
{
10-
11+
{
12+
this.serviceProvider = serviceProvider;
1113
BrowseForExistingProjectCommand = new AnonymousTaskCommand(serviceProvider, BrowseForExistingProject);
1214
}
1315
public ICommandBase BrowseForExistingProjectCommand { get; }
1416
public bool AutoReloadSession { get; }
1517

16-
private Task BrowseForExistingProject()
18+
private async Task BrowseForExistingProject()
1719
{
18-
return Task.CompletedTask;
20+
var filePath = await EditorDialogHelper.BrowseForExistingProject(serviceProvider);
1921
}
2022

2123
}

sources/editor/Stride.Core.Assets.Editor.Avalonia/ProjectSelectionWindow.axaml.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net)
22
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
33

4-
using Avalonia;
54
using Avalonia.Controls;
6-
using Avalonia.Markup.Xaml;
75

86
namespace Stride.Core.Assets.Editor.Avalonia;
97

sources/editor/Stride.Core.Assets.Editor.Avalonia/Stride.Core.Assets.Editor.Avalonia.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
<ItemGroup>
1515
<ProjectReference Include="..\..\presentation\Stride.Core.Presentation.Avalonia\Stride.Core.Presentation.Avalonia.csproj" />
1616
<ProjectReference Include="..\..\presentation\Stride.Core.Presentation\Stride.Core.Presentation.csproj" />
17+
<ProjectReference Include="..\Stride.Core.Assets.Editor\Stride.Core.Assets.Editor.csproj" />
1718
</ItemGroup>
1819

1920
<Import Project="$(StrideSdkTargets)" />
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
2+
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Threading.Tasks;
6+
using Stride.Core.Assets.Editor.Settings;
7+
using Stride.Core.Assets.Editor.ViewModel;
8+
using Stride.Core.Extensions;
9+
using Stride.Core.IO;
10+
using Stride.Core.Presentation.Services;
11+
using Stride.Core.Presentation.ViewModels;
12+
13+
namespace Stride.Core.Assets.Editor.Services
14+
{
15+
public static class EditorDialogHelper
16+
{
17+
// TODO: Put ShowMessage here, find a way to reach the editor title from Stride
18+
19+
public static async Task<UFile> BrowseForExistingProject(IViewModelServiceProvider serviceProvider)
20+
{
21+
var initialDirectory = InternalSettings.FileDialogLastOpenSessionDirectory.GetValue();
22+
var filters = new List<FilePickerFilter>
23+
{
24+
new("Solution or package files") { Patterns = [EditorViewModel.SolutionFileExtension, EditorViewModel.PackageFileExtension]},
25+
new("Solution file") { Patterns = [EditorViewModel.SolutionFileExtension]},
26+
new("Package file") { Patterns = [EditorViewModel.PackageFileExtension]},
27+
};
28+
var filePaths = await OpenFileDialog(serviceProvider, false, initialDirectory, filters);
29+
return filePaths?.FirstOrDefault();
30+
}
31+
32+
public static async Task<IEnumerable<UFile>> OpenFileDialog(IViewModelServiceProvider serviceProvider, bool allowMultiSelection, string initialDirectory, IReadOnlyList<FilePickerFilter> filters = null)
33+
{
34+
if (allowMultiSelection)
35+
{
36+
var files = await serviceProvider.Get<IDialogService>().OpenMultipleFilesPickerAsync(initialDirectory, filters);
37+
return files.Count > 0 ? files : null;
38+
}
39+
else
40+
{
41+
var file = await serviceProvider.Get<IDialogService>().OpenFilePickerAsync(initialDirectory, filters);
42+
return file?.Yield();
43+
}
44+
}
45+
}
46+
}
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
2+
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
3+
using System;
4+
using System.Collections.Generic;
5+
using System.IO;
6+
using System.Linq;
7+
using Stride.Core.Assets.Editor.ViewModel;
8+
using Stride.Core.Assets.Editor.ViewModels;
9+
using Stride.Core.IO;
10+
using Stride.Core.Settings;
11+
using Stride.Core.Yaml;
12+
using Stride.Core.MostRecentlyUsedFiles;
13+
using Stride.Core.Presentation.Collections;
14+
using static Stride.Core.Assets.Editor.ViewModel.AssetCollectionViewModel;
15+
16+
namespace Stride.Core.Assets.Editor.Settings
17+
{
18+
public static class InternalSettings
19+
{
20+
public static SettingsContainer SettingsContainer = new();
21+
22+
public static SettingsKey<MRUDictionary> MostRecentlyUsedSessions = new("Internal/MostRecentlyUsedSessions", SettingsContainer, () => new MRUDictionary());
23+
public static SettingsKey<bool> LoadingStartupSession = new("Internal/LoadingStartupSession", SettingsContainer, false);
24+
public static SettingsKey<string> FileDialogLastImportDirectory = new("Internal/FileDialogLastImportDirectory", SettingsContainer, "");
25+
public static SettingsKey<string> FileDialogLastOpenSessionDirectory = new("Internal/FileDialogLastOpenSessionDirectory", SettingsContainer, "");
26+
public static SettingsKey<string> TemplatesWindowDialogLastNewSessionTemplateDirectory = new("Internal/TemplatesWindowDialogLastNewSessionTemplateDirectory", SettingsContainer, "");
27+
public static SettingsKey<SortRule> AssetViewSortRule = new("Internal/AssetViewSortRule", SettingsContainer, SortRule.TypeOrderThenName);
28+
public static SettingsKey<DisplayAssetMode> AssetViewDisplayMode = new("Internal/AssetViewDisplayMode", SettingsContainer, DisplayAssetMode.AssetAndFolderInSelectedFolder);
29+
public static SettingsKey<double> AssetViewTileThumbnailZoom = new("Internal/AssetViewTileThumbnailZoom", SettingsContainer, 96.0);
30+
public static SettingsKey<double> AssetViewGridThumbnailZoom = new("Internal/AssetViewGridThumbnailZoom", SettingsContainer, 16.0);
31+
public static SettingsKey<List<AssetFilterViewModelData>> ViewFilters = new("Internal/CurrentAssetFilters", SettingsContainer, () => new List<AssetFilterViewModelData>());
32+
33+
private static readonly SettingsProfile Profile;
34+
35+
static InternalSettings()
36+
{
37+
MostRecentlyUsedSessions.FallbackDeserializers.Add(LegacyMRUDeserializer);
38+
Profile = LoadProfile(true);
39+
SettingsContainer.CurrentProfile = Profile;
40+
}
41+
42+
/// <summary>
43+
/// Loads a copy of the internal settings from the file.
44+
/// </summary>
45+
/// <returns></returns>
46+
public static SettingsProfile LoadProfileCopy()
47+
{
48+
return LoadProfile(false);
49+
}
50+
51+
/// <summary>
52+
/// Loads a copy of the internal settings from the file.
53+
/// </summary>
54+
/// <returns></returns>
55+
private static SettingsProfile LoadProfile(bool registerProfile)
56+
{
57+
return SettingsContainer.LoadSettingsProfile(GetLatestInternalConfigPath(), false, null, registerProfile) ?? SettingsContainer.CreateSettingsProfile(false);
58+
}
59+
60+
/// <summary>
61+
/// Saves the settings into the settings file.
62+
/// </summary>
63+
public static void Save()
64+
{
65+
// Special case for MRU: we always reload the latest version from the file.
66+
// Actually modifying and saving MRU is done in a specific class.
67+
var profileCopy = LoadProfileCopy();
68+
var mruList = MostRecentlyUsedSessions.GetValue(profileCopy, true);
69+
MostRecentlyUsedSessions.SetValue(mruList);
70+
WriteFile();
71+
}
72+
73+
/// <summary>
74+
/// Saves the settings into the settings file.
75+
/// </summary>
76+
public static void WriteFile()
77+
{
78+
SettingsContainer.SaveSettingsProfile(Profile, EditorPath.InternalConfigPath);
79+
}
80+
81+
private static object LegacyMRUDeserializer(EventReader eventReader)
82+
{
83+
const string legacyVersion = "1.3";
84+
var mru = (List<UFile>)SettingsYamlSerializer.Default.Deserialize(eventReader, typeof(List<UFile>));
85+
var initialTimestamp = DateTime.UtcNow.Ticks;
86+
return new Dictionary<string, List<MostRecentlyUsedFile>>
87+
{
88+
{ legacyVersion, mru.Select(x => new MostRecentlyUsedFile(x) { Timestamp = initialTimestamp-- }).ToList() }
89+
};
90+
}
91+
92+
private static string GetLatestInternalConfigPath()
93+
{
94+
return GetInternalConfigPaths().FirstOrDefault(File.Exists) ?? EditorPath.InternalConfigPath;
95+
}
96+
97+
private static IEnumerable<string> GetInternalConfigPaths()
98+
{
99+
yield return EditorPath.InternalConfigPath;
100+
}
101+
}
102+
}

sources/editor/Stride.Core.Assets.Editor/Stride.Core.Assets.Editor.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,6 @@
1919
<ProjectReference Include="..\..\editor\Stride.Core.Assets.Presentation\Stride.Core.Assets.Presentation.csproj" />
2020
</ItemGroup>
2121

22+
<Import Project="..\..\editor\Stride.Core.MostRecentlyUsedFiles\Stride.Core.MostRecentlyUsedFiles.projitems" Label="Shared" />
2223
<Import Project="$(StrideSdkTargets)" />
2324
</Project>

sources/editor/Stride.Core.Assets.Editor/ViewModels/AssetCollectionViewModel.cs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,37 @@
1010

1111
namespace Stride.Core.Assets.Editor.ViewModels;
1212

13+
public enum DisplayAssetMode
14+
{
15+
AssetInSelectedFolderOnly,
16+
AssetInSelectedFolderAndSubFolder,
17+
AssetAndFolderInSelectedFolder,
18+
}
19+
20+
public enum FilterCategory
21+
{
22+
AssetName,
23+
AssetTag,
24+
AssetType,
25+
}
26+
27+
public enum SortRule
28+
{
29+
Name,
30+
TypeOrderThenName,
31+
DirtyThenName,
32+
ModificationDateThenName,
33+
}
34+
35+
[DataContract(nameof(AssetFilterViewModelData))]
36+
public sealed class AssetFilterViewModelData
37+
{
38+
public string DisplayName = "";
39+
public string Filter = "";
40+
public bool IsActive = false;
41+
public FilterCategory category = FilterCategory.AssetName;
42+
}
43+
1344
public sealed class AssetCollectionViewModel : DispatcherViewModel
1445
{
1546
private readonly ObservableSet<AssetViewModel> assets = [];

sources/editor/Stride.Core.MostRecentlyUsedFiles/MostRecentlyUsedFileCollection.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,7 @@ namespace Stride.Core.MostRecentlyUsedFiles
1414
{
1515
// TODO: this is a hack because YamlSerializer is static and there is no way to disable serialization with Id for Settings at the moment. This is temporary!
1616
[NonIdentifiableCollectionItems]
17-
public class MRUDictionary : Dictionary<string, List<MostRecentlyUsedFile>>
18-
{
19-
20-
}
17+
public class MRUDictionary : Dictionary<string, List<MostRecentlyUsedFile>>;
2118

2219
/// <summary>
2320
/// A class that handles a list of most recently used (MRU) files.

sources/editor/Stride.GameStudio.Avalonia/App.axaml.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,12 @@ public void Restart(UFile? initialPath = null)
5555
}
5656
}
5757

58-
private static MainViewModel InitializeMainViewModel(UFile? initialPath)
58+
private static object InitializeMainViewModel(UFile? initialPath)
5959
{
60-
var viewmodel = new MainViewModel(InitializeServiceProvider());
61-
if (initialPath is not null)
62-
viewmodel.OpenCommand.Execute(initialPath);
60+
//Switch viewmodel depending the program arguments
61+
var viewmodel = new NewOrOpenSessionTemplateCollectionViewModel(InitializeServiceProvider());
62+
// if (initialPath is not null)
63+
// vm.OpenCommand.Execute(initialPath);
6364
return viewmodel;
6465
}
6566

0 commit comments

Comments
 (0)