-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: setup the project explorer view
- Loading branch information
Showing
16 changed files
with
739 additions
and
77 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
26 changes: 26 additions & 0 deletions
26
projects/Oxygen.Editor.WorldEditor/src/ProjectExplorer/EntityAdapter.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// Distributed under the MIT License. See accompanying file LICENSE or copy | ||
// at https://opensource.org/licenses/MIT. | ||
// SPDX-License-Identifier: MIT | ||
|
||
namespace Oxygen.Editor.WorldEditor.ProjectExplorer; | ||
|
||
using DroidNet.Controls; | ||
using Oxygen.Editor.Projects; | ||
|
||
/// <summary> | ||
/// A <see cref="DynamicTree" /> item adapter for the <see cref="Entity" /> model class. | ||
/// </summary> | ||
/// <param name="entity">The <see cref="Entity" /> object to wrap as a <see cref="ITreeItem" />.</param> | ||
public partial class EntityAdapter(Entity entity) : TreeItemAdapter, ITreeItem<Entity> | ||
{ | ||
public override bool IsRoot => false; | ||
|
||
public override string Label | ||
=> this.AttachedObject.Name; | ||
|
||
public Entity AttachedObject => entity; | ||
|
||
protected override int GetChildrenCount() => 0; | ||
|
||
protected override async Task LoadChildren() => await Task.CompletedTask.ConfigureAwait(false); | ||
} |
44 changes: 44 additions & 0 deletions
44
projects/Oxygen.Editor.WorldEditor/src/ProjectExplorer/ProjectAdapter.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
// Distributed under the MIT License. See accompanying file LICENSE or copy | ||
// at https://opensource.org/licenses/MIT. | ||
// SPDX-License-Identifier: MIT | ||
|
||
namespace Oxygen.Editor.WorldEditor.ProjectExplorer; | ||
|
||
using DroidNet.Controls; | ||
using Oxygen.Editor.Projects; | ||
|
||
/// <summary> | ||
/// A <see cref="DynamicTree" /> item adapter for the <see cref="Project" /> model class. | ||
/// </summary> | ||
/// <param name="project">The <see cref="Entity" /> object to wrap as a <see cref="ITreeItem" />.</param> | ||
/// <param name="projectManager">The configured project manager service.</param> | ||
public partial class ProjectAdapter(Project project, IProjectManagerService projectManager) | ||
: TreeItemAdapter, ITreeItem<Project> | ||
{ | ||
public override string Label => project.ProjectInfo.Name; | ||
|
||
public Project AttachedObject => project; | ||
|
||
protected override int GetChildrenCount() => project.Scenes.Count; | ||
|
||
protected override async Task LoadChildren() | ||
{ | ||
this.ClearChildren(); | ||
|
||
if (!await projectManager.LoadProjectScenesAsync(project).ConfigureAwait(false)) | ||
{ | ||
return; | ||
} | ||
|
||
foreach (var scene in project.Scenes) | ||
{ | ||
this.AddChildInternal( | ||
new SceneAdapter(scene, projectManager) | ||
{ | ||
IsExpanded = true, | ||
}); | ||
} | ||
|
||
await Task.CompletedTask.ConfigureAwait(true); | ||
} | ||
} |
122 changes: 122 additions & 0 deletions
122
projects/Oxygen.Editor.WorldEditor/src/ProjectExplorer/ProjectExplorerView.xaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
<?xml version="1.0" encoding="utf-8" ?> | ||
<UserControl | ||
x:Class="Oxygen.Editor.WorldEditor.ProjectExplorer.ProjectExplorerView" | ||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | ||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | ||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | ||
xmlns:dnc="using:DroidNet.Controls" | ||
xmlns:local="using:Oxygen.Editor.WorldEditor.ProjectExplorer" | ||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | ||
KeyboardAcceleratorPlacementMode="Hidden" | ||
mc:Ignorable="d"> | ||
|
||
<UserControl.Resources> | ||
<ResourceDictionary> | ||
<ResourceDictionary.MergedDictionaries> | ||
<ResourceDictionary Source="ms-appx:///DroidNet.Controls.DynamicTree/DynamicTree/DynamicTree.xaml" /> | ||
</ResourceDictionary.MergedDictionaries> | ||
|
||
<DataTemplate x:Key="SceneThumbnailTemplate" x:DataType="dnc:TreeItemAdapter"> | ||
<Image Source="{x:Bind local:ThumbnailGenerator.GenerateRandomImage(24, 24)}" /> | ||
</DataTemplate> | ||
|
||
<DataTemplate x:Key="EntityThumbnailTemplate" x:DataType="dnc:TreeItemAdapter"> | ||
<SymbolIcon | ||
Width="24" | ||
Height="24" | ||
Symbol="{x:Bind local:ThumbnailGenerator.GetThumbnailForEntity((dnc:TreeItemAdapter))}" /> | ||
</DataTemplate> | ||
|
||
<DataTemplate x:Key="DefaultThumbnailTemplate"> | ||
<Border | ||
Width="{StaticResource CellContentWidth}" | ||
Height="{StaticResource CellContentHeight}" | ||
BorderBrush="{ThemeResource EmptyThumbnailBorderColor}" | ||
BorderThickness="1" /> | ||
</DataTemplate> | ||
|
||
<local:ThumbnailTemplateSelector | ||
x:Key="ThumbnailTemplateSelector" | ||
DefaultTemplate="{StaticResource DefaultThumbnailTemplate}" | ||
EntityTemplate="{StaticResource EntityThumbnailTemplate}" | ||
SceneTemplate="{StaticResource SceneThumbnailTemplate}" /> | ||
</ResourceDictionary> | ||
|
||
</UserControl.Resources> | ||
|
||
<UserControl.KeyboardAccelerators> | ||
<KeyboardAccelerator | ||
Key="Z" | ||
Invoked="UndoInvoked" | ||
Modifiers="Control" /> | ||
<KeyboardAccelerator | ||
Key="Y" | ||
Invoked="RedoInvoked" | ||
Modifiers="Control" /> | ||
<KeyboardAccelerator Key="Delete" Invoked="DeleteInvoked" /> | ||
</UserControl.KeyboardAccelerators> | ||
|
||
<Grid | ||
Padding="4" | ||
HorizontalAlignment="Stretch" | ||
VerticalAlignment="Stretch"> | ||
<Grid.RowDefinitions> | ||
<RowDefinition Height="*" /> | ||
<RowDefinition Height="Auto" /> | ||
</Grid.RowDefinitions> | ||
<Border | ||
Padding="0,3" | ||
BorderBrush="Red" | ||
BorderThickness="1" | ||
CornerRadius="3"> | ||
<dnc:DynamicTree | ||
SelectionMode="Multiple" | ||
ThumbnailTemplateSelector="{StaticResource ThumbnailTemplateSelector}" | ||
ViewModel="{x:Bind ViewModel}" /> | ||
</Border> | ||
<Grid Grid.Row="1"> | ||
<Grid.Resources> | ||
<Style TargetType="AppBarButton"> | ||
<Setter Property="Width" Value="40" /> | ||
</Style> | ||
</Grid.Resources> | ||
|
||
<Grid.ColumnDefinitions> | ||
<ColumnDefinition Width="*" /> | ||
<ColumnDefinition Width="Auto" /> | ||
</Grid.ColumnDefinitions> | ||
<CommandBar | ||
Grid.Column="1" | ||
DefaultLabelPosition="Collapsed" | ||
OverflowButtonVisibility="Collapsed"> | ||
<AppBarButton | ||
Icon="Rename" | ||
IsCompact="True" | ||
Label="Rename" /> | ||
<AppBarButton | ||
Icon="Repair" | ||
IsCompact="True" | ||
Label="Edit Properties" /> | ||
<AppBarButton | ||
Command="{x:Bind ViewModel.AddEntityCommand}" | ||
IsCompact="True" | ||
Label="Add Entity"> | ||
<AppBarButton.Icon> | ||
<FontIcon Glyph="" /> | ||
</AppBarButton.Icon> | ||
</AppBarButton> | ||
<AppBarButton | ||
Command="{x:Bind ViewModel.AddSceneCommand}" | ||
Icon="Add" | ||
IsCompact="True" | ||
Label="Create New Scene" /> | ||
<AppBarButton | ||
Command="{x:Bind ViewModel.RemoveSelectedItemsCommand}" | ||
Icon="Delete" | ||
IsCompact="True" | ||
Label="Delete" | ||
ToolTipService.ToolTip="Delete (Del)" /> | ||
</CommandBar> | ||
</Grid> | ||
</Grid> | ||
</UserControl> |
62 changes: 62 additions & 0 deletions
62
projects/Oxygen.Editor.WorldEditor/src/ProjectExplorer/ProjectExplorerView.xaml.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
// Distributed under the MIT License. See accompanying file LICENSE or copy | ||
// at https://opensource.org/licenses/MIT. | ||
// SPDX-License-Identifier: MIT | ||
|
||
namespace Oxygen.Editor.WorldEditor.ProjectExplorer; | ||
|
||
using DroidNet.Controls; | ||
using DroidNet.Mvvm.Generators; | ||
using Microsoft.UI.Xaml; | ||
using Microsoft.UI.Xaml.Input; | ||
using Oxygen.Editor.Projects; | ||
|
||
/// <summary> | ||
/// A View that shows a hierarchical layout of a <see cref="Project">project</see> that has <see cref="Scene">scenes</see>, which | ||
/// in turn can hold multiple <see cref="Entity">entities</see>. It demonstrates the flexibility of the <see cref="DynamicTree" /> | ||
/// in representing hierarchical layouts of mixed types which can be loaded dynamically. | ||
/// </summary> | ||
[ViewModel(typeof(ProjectExplorerViewModel))] | ||
public sealed partial class ProjectExplorerView | ||
{ | ||
public ProjectExplorerView() | ||
{ | ||
this.InitializeComponent(); | ||
|
||
this.Loaded += this.OnLoaded; | ||
} | ||
|
||
private async void OnLoaded(object sender, RoutedEventArgs args) | ||
{ | ||
_ = sender; // unused | ||
_ = args; // unused | ||
|
||
if (this.ViewModel is not null) | ||
{ | ||
await this.ViewModel.LoadProjectCommand.ExecuteAsync(parameter: null).ConfigureAwait(true); | ||
} | ||
} | ||
|
||
private void UndoInvoked(KeyboardAccelerator sender, KeyboardAcceleratorInvokedEventArgs args) | ||
{ | ||
_ = sender; // unused | ||
args.Handled = true; | ||
|
||
this.ViewModel!.UndoCommand.Execute(parameter: null); | ||
} | ||
|
||
private void RedoInvoked(KeyboardAccelerator sender, KeyboardAcceleratorInvokedEventArgs args) | ||
{ | ||
_ = sender; // unused | ||
args.Handled = true; | ||
|
||
this.ViewModel!.RedoCommand.Execute(parameter: null); | ||
} | ||
|
||
private async void DeleteInvoked(KeyboardAccelerator sender, KeyboardAcceleratorInvokedEventArgs args) | ||
{ | ||
_ = sender; // unused | ||
args.Handled = true; | ||
|
||
await this.ViewModel!.RemoveSelectedItemsCommand.ExecuteAsync(parameter: null).ConfigureAwait(false); | ||
} | ||
} |
Oops, something went wrong.