Skip to content

Commit df3d891

Browse files
committed
[Editor] FetchEntity command
1 parent fa40bee commit df3d891

File tree

6 files changed

+109
-9
lines changed

6 files changed

+109
-9
lines changed

sources/editor/Stride.Assets.Editor.Avalonia/Views/EntityPropertyTemplateProviders.axaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@
8989
<UniformGrid Rows="1" DockPanel.Dock="Right">
9090
<Button IsVisible="{Binding [HasCommand_PickupEntity]}"
9191
Command="{Binding [PickupEntity]}"
92-
CommandParameter="{sd:MultiBinding {Binding [OwnerAsset]}, {Binding Source={x:Null}},
92+
CommandParameter="{sd:MultiBinding {Binding [OwnerAsset]}, {Binding Source={x:Static AvaloniaProperty.UnsetValue}},
9393
Converter={sd:MultiToTuple}}"
9494
ToolTip.Tip="{sd:LocalizeString Select an asset, Context=ToolTip}">
9595
<Image Source="{StaticResource ImagePickup}" Width="16" Height="16"/>
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net)
2+
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
3+
4+
using Stride.Assets.Editor.ViewModels;
5+
using Stride.Assets.Presentation.ViewModels;
6+
using Stride.Core;
7+
using Stride.Core.Assets.Editor.Services;
8+
using Stride.Core.Presentation.Quantum.Presenters;
9+
using Stride.Engine;
10+
11+
namespace Stride.Assets.Editor.Quantum.NodePresenters.Commands;
12+
13+
internal sealed class FetchEntityCommand : SyncNodePresenterCommandBase
14+
{
15+
/// <summary>
16+
/// The name of this command.
17+
/// </summary>
18+
public const string CommandName = "FetchEntity";
19+
20+
/// <inheritdoc/>
21+
public override string Name => CommandName;
22+
23+
public override bool CanAttach(INodePresenter nodePresenter)
24+
{
25+
return typeof(Entity).IsAssignableFrom(nodePresenter.Type) || typeof(EntityComponent).IsAssignableFrom(nodePresenter.Type);
26+
}
27+
28+
protected override void ExecuteSync(INodePresenter nodePresenter, object? parameter, object? preExecuteResult)
29+
{
30+
if (parameter is EntityHierarchyViewModel hierarchy)
31+
{
32+
Fetch(hierarchy, nodePresenter.Value);
33+
}
34+
}
35+
36+
/// <summary>
37+
/// Fetches the entity corresponding to the given content.
38+
/// </summary>
39+
/// <param name="hierarchy">The hierarchy owning the entity to fetch.</param>
40+
/// <param name="content">The entity to fetch, or one of its components.</param>
41+
public static void Fetch(EntityHierarchyViewModel hierarchy, object content)
42+
{
43+
var entity = content is EntityComponent component ? component.Entity : content as Entity;
44+
if (entity is null)
45+
return;
46+
47+
if (!hierarchy.ServiceProvider.Get<IAssetEditorsManager>().TryGetAssetEditor<EntityHierarchyEditorViewModel>(hierarchy, out var editor))
48+
return;
49+
50+
var partId = new AbsoluteId(hierarchy.Id, entity.Id);
51+
if (editor.FindPartViewModel(partId) is not EntityViewModel viewModel)
52+
return;
53+
54+
editor.SelectedItems.Clear();
55+
editor.SelectedItems.Add(viewModel);
56+
// FIXME xplat-editor
57+
//editor.Controller.GetService<IEditorGameEntityCameraViewModelService>().CenterOnEntity(viewModel);
58+
}
59+
}

sources/editor/Stride.Assets.Editor/StrideEditorPlugin.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ public override void InitializeSession(ISessionViewModel session)
6363
if (session is SessionViewModel sessionVm)
6464
{
6565
// commands
66+
sessionVm.ActiveProperties.RegisterNodePresenterCommand(new FetchEntityCommand());
6667
sessionVm.ActiveProperties.RegisterNodePresenterCommand(new SetComponentReferenceCommand());
6768
sessionVm.ActiveProperties.RegisterNodePresenterCommand(new SetEntityReferenceCommand());
6869

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net)
2+
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
3+
4+
using System.Diagnostics.CodeAnalysis;
5+
using Stride.Core.Assets.Editor.ViewModels;
6+
using Stride.Core.Assets.Presentation.ViewModels;
7+
8+
namespace Stride.Core.Assets.Editor.Services;
9+
10+
public interface IAssetEditorsManager
11+
{
12+
/// <summary>
13+
/// Try to find an opened editor for the given asset.
14+
/// </summary>
15+
/// <typeparam name="TEditor"></typeparam>
16+
/// <param name="asset"></param>
17+
/// <param name="assetEditor"></param>
18+
/// <returns></returns>
19+
bool TryGetAssetEditor<TEditor>(AssetViewModel asset, [MaybeNullWhen(false)] out TEditor assetEditor) where TEditor : AssetEditorViewModel;
20+
}

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ protected virtual void SelectedItemsCollectionChanged(NotifyCollectionChangedAct
103103
SelectedContent.AddRange(SelectedItems);
104104
}
105105

106-
private async void SelectedContentCollectionChanged(object? sender, NotifyCollectionChangedEventArgs args)
106+
private void SelectedContentCollectionChanged(object? sender, NotifyCollectionChangedEventArgs args)
107107
{
108108
if (updateSelectionGuard)
109109
return;
@@ -112,16 +112,16 @@ private async void SelectedContentCollectionChanged(object? sender, NotifyCollec
112112
{
113113
updateSelectionGuard = true;
114114
SelectedContentCollectionChanged(args.Action);
115-
// Refresh the property grid
116-
await RefreshEditorProperties();
115+
// Refresh the property grid asynchronously
116+
RefreshEditorProperties().Forget();
117117
}
118118
finally
119119
{
120120
updateSelectionGuard = false;
121121
}
122122
}
123123

124-
private async void SelectedItemsCollectionChanged(object? sender, NotifyCollectionChangedEventArgs args)
124+
private void SelectedItemsCollectionChanged(object? sender, NotifyCollectionChangedEventArgs args)
125125
{
126126
if (updateSelectionGuard)
127127
return;
@@ -130,8 +130,8 @@ private async void SelectedItemsCollectionChanged(object? sender, NotifyCollecti
130130
{
131131
updateSelectionGuard = true;
132132
SelectedItemsCollectionChanged(args.Action);
133-
// Refresh the property grid
134-
await RefreshEditorProperties();
133+
// Refresh the property grid asynchronously
134+
RefreshEditorProperties().Forget();
135135
}
136136
finally
137137
{

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

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
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 System.Diagnostics.CodeAnalysis;
45
using Stride.Core.Assets.Editor.Services;
56
using Stride.Core.Assets.Presentation.ViewModels;
67
using Stride.Core.Presentation.Collections;
78
using Stride.Core.Presentation.ViewModels;
89

910
namespace Stride.Core.Assets.Editor.ViewModels;
1011

11-
// TODO might not be needed, we can have an OpenedAssets collection in AssetCollectionViewModel
12-
public sealed class EditorCollectionViewModel : DispatcherViewModel
12+
public sealed class EditorCollectionViewModel : DispatcherViewModel, IAssetEditorsManager
1313
{
1414
private AssetEditorViewModel? activeEditor;
1515
private readonly ObservableList<AssetEditorViewModel> editors = [];
@@ -19,6 +19,14 @@ public EditorCollectionViewModel(SessionViewModel session)
1919
: base(session.ServiceProvider)
2020
{
2121
Session = session;
22+
ServiceProvider.RegisterService(this);
23+
}
24+
25+
public override void Destroy()
26+
{
27+
EnsureNotDestroyed(nameof(EditorCollectionViewModel));
28+
ServiceProvider.UnregisterService(this);
29+
base.Destroy();
2230
}
2331

2432
public AssetEditorViewModel? ActiveEditor
@@ -48,4 +56,16 @@ public void OpenAssetEditor(AssetViewModel asset)
4856
ActiveEditor = editor;
4957
}
5058
}
59+
60+
public bool TryGetAssetEditor<TEditor>(AssetViewModel asset, [MaybeNullWhen(false)] out TEditor assetEditor) where TEditor : AssetEditorViewModel
61+
{
62+
if (openedAssets.TryGetValue(asset, out var found) && found is TEditor editor)
63+
{
64+
assetEditor = editor;
65+
return true;
66+
}
67+
68+
assetEditor = null;
69+
return false;
70+
}
5171
}

0 commit comments

Comments
 (0)