port from perforce
This commit is contained in:
171
intromat/Intromat/ViewModels/MainViewModel.cs
Normal file
171
intromat/Intromat/ViewModels/MainViewModel.cs
Normal file
@@ -0,0 +1,171 @@
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reactive;
|
||||
using System.Reactive.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Intromat.PersistentModel;
|
||||
using Intromat.ViewModels.Nodes;
|
||||
using Intromat.ViewModels.Previews;
|
||||
using NodeNetwork.Toolkit.Group;
|
||||
using NodeNetwork.Toolkit.NodeList;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Intromat.ViewModels
|
||||
{
|
||||
public class MainViewModel : ReactiveObject
|
||||
{
|
||||
private ProjectViewModel _project;
|
||||
private FileViewModel? _activeFile;
|
||||
private object? _propertiesContext;
|
||||
private DxTexturePreviewViewModel? _preview2dContext;
|
||||
private DxMeshPreviewViewModel? _preview3dContext;
|
||||
|
||||
public MainViewModel()
|
||||
{
|
||||
AppState = ((AppStateViewModel)RxApp.SuspensionHost.AppState!)!;
|
||||
Explorer = new(this);
|
||||
|
||||
var desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
|
||||
var initialProjectPath = Path.Combine(desktopPath, "Project1", "Project1.iproj");
|
||||
if (File.Exists(initialProjectPath))
|
||||
{
|
||||
_project = Task.Run(() => ProjectSerializer.LoadProject(this, initialProjectPath)).GetAwaiter().GetResult()!;
|
||||
}
|
||||
else
|
||||
{
|
||||
_project = ProjectViewModel.CreateDefault(this, initialProjectPath, "Project1");
|
||||
}
|
||||
|
||||
foreach (var nodeType in typeof(CodeGenNodeViewModel).Assembly.ExportedTypes.Where(t => typeof(CodeGenNodeViewModel).IsAssignableFrom(t) && !t.IsAbstract))
|
||||
{
|
||||
if (nodeType.Namespace == $"{nameof(Intromat)}.{nameof(Nodes)}")
|
||||
continue;
|
||||
|
||||
NodeList.AddNodeType(() => (CodeGenNodeViewModel)Activator.CreateInstance(nodeType)!);
|
||||
}
|
||||
|
||||
Grouper = new NodeGrouper
|
||||
{
|
||||
GroupNodeFactory = subnet => new GroupNodeViewModel
|
||||
{
|
||||
Name = "Group",
|
||||
Subnet = (CodeGenNetworkViewModel)subnet
|
||||
},
|
||||
EntranceNodeFactory = () => new GroupSubnetIONodeViewModel
|
||||
{
|
||||
IsEntranceNode = true
|
||||
},
|
||||
ExitNodeFactory = () => new GroupSubnetIONodeViewModel
|
||||
{
|
||||
IsEntranceNode = false
|
||||
},
|
||||
SubNetworkFactory = parentNet =>
|
||||
{
|
||||
var subNetwork = new CodeGenNetworkViewModel(((CodeGenNetworkViewModel)parentNet).Document, "Group") { ParentNetwork = (CodeGenNetworkViewModel)parentNet };
|
||||
return subNetwork;
|
||||
},
|
||||
IOBindingFactory = (groupNode, entranceNode, exitNode) =>
|
||||
new CodeNodeGroupIOBinding(groupNode, entranceNode, exitNode)
|
||||
};
|
||||
|
||||
LoadProject = ReactiveCommand.CreateFromTask(async () =>
|
||||
{
|
||||
var file = await OpenProjectFile.Handle(true);
|
||||
if (file == null)
|
||||
return null;
|
||||
|
||||
var activeFile = ActiveFile;
|
||||
if (activeFile != null)
|
||||
UndoRedo.Purge(activeFile);
|
||||
|
||||
UndoRedo.Recording = false;
|
||||
try
|
||||
{
|
||||
return await ProjectSerializer.LoadProject(this, file);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignored, TODO
|
||||
}
|
||||
finally
|
||||
{
|
||||
ActiveFile = null;
|
||||
Files.Clear();
|
||||
UndoRedo.Recording = true;
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
LoadProject.Where(n => n != null).Subscribe(project => Project = project!);
|
||||
|
||||
SaveProject = ReactiveCommand.CreateFromTask(async () =>
|
||||
{
|
||||
await ProjectSerializer.SaveModel(Project);
|
||||
});
|
||||
|
||||
SaveProjectAs = ReactiveCommand.CreateFromTask(() => throw new NotImplementedException());
|
||||
|
||||
this.WhenAnyValue(vm => vm.Project).Subscribe(_ =>
|
||||
{
|
||||
if (Explorer.TreeRoot.Count == 0)
|
||||
Explorer.TreeRoot.Add(Project);
|
||||
else
|
||||
{
|
||||
Explorer.TreeRoot[0] = Project;
|
||||
}
|
||||
});
|
||||
|
||||
this.WhenAnyValue(vm => vm.ActiveFile!.CurrentViewModel).Subscribe(n => PropertiesContext = n);
|
||||
|
||||
UndoRedo.Recording = true;
|
||||
}
|
||||
|
||||
public NodeListViewModel NodeList { get; } = new();
|
||||
public UndoRedoViewModel UndoRedo { get; } = new();
|
||||
public AppStateViewModel AppState { get; }
|
||||
public ExplorerViewModel Explorer { get; }
|
||||
|
||||
public ReactiveCommand<Unit, ProjectViewModel?> LoadProject { get; }
|
||||
public ReactiveCommand<Unit, Unit> SaveProject { get; }
|
||||
public ReactiveCommand<Unit, Unit> SaveProjectAs { get; }
|
||||
public Interaction<bool, string?> OpenProjectFile { get; } = new();
|
||||
public Interaction<Unit, Func<FileViewModel>?> SelectTypeAndFileName { get; } = new();
|
||||
public Interaction<string?, string?> SelectName { get; } = new();
|
||||
|
||||
public NodeGrouper Grouper { get; }
|
||||
|
||||
public ProjectViewModel Project
|
||||
{
|
||||
get => _project;
|
||||
set => this.RaiseAndSetIfChanged(ref _project, value);
|
||||
}
|
||||
|
||||
public ObservableCollection<FileViewModel> Files { get; } = new();
|
||||
|
||||
public FileViewModel? ActiveFile
|
||||
{
|
||||
get => _activeFile;
|
||||
set => this.RaiseAndSetIfChanged(ref _activeFile, value);
|
||||
}
|
||||
|
||||
public object? PropertiesContext
|
||||
{
|
||||
get => _propertiesContext;
|
||||
set => this.RaiseAndSetIfChanged(ref _propertiesContext, value);
|
||||
}
|
||||
|
||||
public DxTexturePreviewViewModel? Preview2dContext
|
||||
{
|
||||
get => _preview2dContext;
|
||||
set => this.RaiseAndSetIfChanged(ref _preview2dContext, value);
|
||||
}
|
||||
|
||||
public DxMeshPreviewViewModel? Preview3dContext
|
||||
{
|
||||
get => _preview3dContext;
|
||||
set => this.RaiseAndSetIfChanged(ref _preview3dContext, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user