Skip to content

Commit

Permalink
Added Open Project to Main Menu and implemented dialog interaction fo…
Browse files Browse the repository at this point in the history
…r opening an existing project.

#27
#28
  • Loading branch information
TheHeadmaster committed Aug 3, 2024
1 parent 2f5f71e commit e0f37e1
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 0 deletions.
10 changes: 10 additions & 0 deletions Horizon/View/Controls/MainMenu.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,16 @@
</MenuItem.Icon>
</MenuItem>
</MenuItem>
<MenuItem Header="Open" InputGestureText="Ctrl+Shift+O">
<MenuItem.Icon>
<Image Source="/Resources/Images/Open Small.png" Width="18" Height="18" />
</MenuItem.Icon>
<MenuItem x:Name="OpenProjectMenuItem" Header="Project...">
<MenuItem.Icon>
<Image Source="/Resources/Images/Open Small.png" Width="18" Height="18" />
</MenuItem.Icon>
</MenuItem>
</MenuItem>
</MenuItem>
</Menu>
</StackPanel>
Expand Down
6 changes: 6 additions & 0 deletions Horizon/View/Controls/MainMenu.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ public MainMenu()
.Select(x => new Unit())
.InvokeCommand(App.CommandsViewModel, x => x.NewProjectDialog)
.DisposeWith(dispose);

this.OpenProjectMenuItem.Events()
.Click
.Select(x => new Unit())
.InvokeCommand(App.CommandsViewModel, x => x.OpenProjectDialog)
.DisposeWith(dispose);
});
}
}
32 changes: 32 additions & 0 deletions Horizon/View/Windows/Workspace.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using AvalonDock;
using Horizon.Converters;
using Horizon.ObjectModel;
using Microsoft.WindowsAPICodePack.Dialogs;
using ReactiveMarbles.ObservableEvents;
using ReactiveUI;
using System.Reactive;
Expand Down Expand Up @@ -124,5 +126,35 @@ private void Interactions(CompositeDisposable dispose)
}, RxApp.MainThreadScheduler);
})
.DisposeWith(dispose);

App.CommandsViewModel
.OpenProjectDialogInteraction
.RegisterHandler(interaction =>
{
CommonOpenFileDialog fileDialog = new() { EnsureFileExists = true, Title = "Select a project file...", Multiselect = false };
fileDialog.Filters.Add(new CommonFileDialogFilter("Project Files", "Project.horizon"));

return Observable.StartAsync(async () =>
{
if (fileDialog.ShowDialog() == CommonFileDialogResult.Ok)
{
ProjectFile? project = await JsonFile.FromAbstractFile<ProjectFile>(fileDialog.FileName);

if (project is not null)
{
interaction.SetOutput(project);
}
else
{
interaction.SetOutput(null);
}
}
else
{
interaction.SetOutput(null);
}
}, RxApp.MainThreadScheduler);
})
.DisposeWith(dispose);
}
}
25 changes: 25 additions & 0 deletions Horizon/ViewModel/CommandsViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,24 @@ public sealed class CommandsViewModel : ReactiveObject
public CommandsViewModel()
{
this.NewProjectDialog = ReactiveCommand.CreateFromTask(this.HandleNewProjectDialog);
this.OpenProjectDialog = ReactiveCommand.CreateFromTask(this.HandleOpenProjectDialog);
}

/// <summary>
/// Command that opens a "new Project" dialog and waits for the interaction to complete.
/// </summary>
public ReactiveCommand<Unit, Unit> NewProjectDialog { get; set; }

/// <summary>
/// Command that opens an "Open Project" file picker and waits for the interaction to complete.
/// </summary>
public ReactiveCommand<Unit, Unit> OpenProjectDialog { get; set; }

/// <summary>
/// Interaction that handles the "Open Project" dialog without blocking the UI.
/// </summary>
public Interaction<Unit, ProjectFile?> OpenProjectDialogInteraction { get; } = new();

/// <summary>
/// Interaction that handles the "New Project" dialog without blocking the UI.
/// </summary>
Expand Down Expand Up @@ -74,6 +85,20 @@ private static async Task OpenProject(ProjectFile project)
await LoadProject(project);
}

/// <summary>
/// Handles the "Open Project" dialog and opens the selected project if the input is accepted.
/// </summary>
/// <returns>An awaitable <see cref="Task" />.</returns>
private async Task HandleOpenProjectDialog()
{
ProjectFile? project = await this.OpenProjectDialogInteraction.Handle(Unit.Default);

if (project is not null)
{
await OpenProject(project);
}
}

/// <summary>
/// handles the "New Project" dialog and creates a new project if the input is accepted.
/// </summary>
Expand Down

0 comments on commit e0f37e1

Please sign in to comment.