Refactor application structure and add database support
Changed App.xaml.cs to implement dependency injection with Microsoft.Extensions.Hosting, initializing services for LandingWindow and LandingViewModel. Removed MainWindow.xaml and MainWindow.xaml.cs, shifting to a new landing window structure. Added Ghost.Database project with necessary database functionality and created ProjectRepository for project management. Added ProjectInfo and TemplateInfo data models for project attributes. Added CreateProjectViewModel and LandingViewModel for managing view models using Community Toolkit for MVVM. Created new XAML pages for project creation, opening projects, and the landing window, along with their corresponding code-behind files. Added AssemblyInfo.cs for internal visibility to facilitate testing.
This commit is contained in:
63
Ghost.Database/DataContext/ProjectRepository.cs
Normal file
63
Ghost.Database/DataContext/ProjectRepository.cs
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
using Ghost.Database.Models.Projects;
|
||||||
|
using System.Data.SQLite;
|
||||||
|
|
||||||
|
namespace Ghost.Database.DataContext;
|
||||||
|
|
||||||
|
public class ProjectRepository
|
||||||
|
{
|
||||||
|
private const string _CONNECTION_STRING = "Data Source={0}/projects.db;Version=3;";
|
||||||
|
private const string _CREATE_PROJECT_TABLE_STRING = "CREATE TABLE IF NOT EXISTS Projects (ID INTEGER PRIMARY KEY AUTOINCREMENT, Name TEXT, Path TEXT, EngineVersion TEXT, LastOpened DATETIME);";
|
||||||
|
private const string _SELECT_PROJECT_STRING = "SELECT * FROM Projects";
|
||||||
|
private const string _INSERT_PROJECT_STRING = "INSERT INTO Projects (Name, Path, EngineVersion, LastOpened) VALUES (@Name, @Path, @EngineVersion, @LastOpened);";
|
||||||
|
|
||||||
|
private static string GetConnectionString() => string.Format(_CONNECTION_STRING, Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData));
|
||||||
|
|
||||||
|
private static void EnsureTableCreated(SQLiteConnection connection)
|
||||||
|
{
|
||||||
|
using var createCommand = connection.CreateCommand();
|
||||||
|
createCommand.CommandText = _CREATE_PROJECT_TABLE_STRING;
|
||||||
|
createCommand.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<ProjectInfo> LoadProjects()
|
||||||
|
{
|
||||||
|
using var connection = new SQLiteConnection(GetConnectionString());
|
||||||
|
connection.Open();
|
||||||
|
|
||||||
|
EnsureTableCreated(connection);
|
||||||
|
|
||||||
|
using var command = connection.CreateCommand();
|
||||||
|
command.CommandText = _SELECT_PROJECT_STRING;
|
||||||
|
|
||||||
|
using var reader = command.ExecuteReader();
|
||||||
|
while (reader.Read())
|
||||||
|
{
|
||||||
|
var project = new ProjectInfo
|
||||||
|
{
|
||||||
|
Name = reader.GetString(0),
|
||||||
|
Path = reader.GetString(1),
|
||||||
|
EngineVersion = new Version(reader.GetString(2)),
|
||||||
|
LastOpened = reader.GetDateTime(3)
|
||||||
|
};
|
||||||
|
|
||||||
|
yield return project;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void AddProject(ProjectInfo project)
|
||||||
|
{
|
||||||
|
using var connection = new SQLiteConnection(GetConnectionString());
|
||||||
|
connection.Open();
|
||||||
|
|
||||||
|
EnsureTableCreated(connection);
|
||||||
|
|
||||||
|
using var command = connection.CreateCommand();
|
||||||
|
command.CommandText = _INSERT_PROJECT_STRING;
|
||||||
|
|
||||||
|
command.Parameters.AddWithValue("@Name", project.Name);
|
||||||
|
command.Parameters.AddWithValue("@Path", project.Path);
|
||||||
|
command.Parameters.AddWithValue("@EngineVersion", project.EngineVersion.ToString());
|
||||||
|
command.Parameters.AddWithValue("@LastOpened", project.LastOpened);
|
||||||
|
command.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
}
|
||||||
15
Ghost.Database/Ghost.Database.csproj
Normal file
15
Ghost.Database/Ghost.Database.csproj
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net9.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="System.Data.SqlClient" Version="4.9.0" />
|
||||||
|
<PackageReference Include="System.Data.SQLite" Version="1.0.119" />
|
||||||
|
<PackageReference Include="System.Drawing.Common" Version="4.7.3" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
32
Ghost.Database/Models/Projects/ProjectInfo.cs
Normal file
32
Ghost.Database/Models/Projects/ProjectInfo.cs
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
|
||||||
|
namespace Ghost.Database.Models.Projects;
|
||||||
|
|
||||||
|
public class ProjectInfo
|
||||||
|
{
|
||||||
|
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||||
|
public int ID
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public required string Name
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public required string Path
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public required Version EngineVersion
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public required DateTime LastOpened
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
}
|
||||||
24
Ghost.Database/Models/Projects/TemplateInfo.cs
Normal file
24
Ghost.Database/Models/Projects/TemplateInfo.cs
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
namespace Ghost.Database.Models.Projects;
|
||||||
|
|
||||||
|
public class TemplateInfo
|
||||||
|
{
|
||||||
|
public required string Name
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string? Description
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public required Version TemplateVersion
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public required Version EngineVersion
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,9 @@
|
|||||||
using Microsoft.UI.Xaml;
|
using Ghost.Editor.View.Windows;
|
||||||
|
using Ghost.Editor.ViewModel.Windows;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
using Microsoft.UI.Xaml;
|
||||||
|
using System;
|
||||||
|
|
||||||
// To learn more about WinUI, the WinUI project structure,
|
// To learn more about WinUI, the WinUI project structure,
|
||||||
// and more about our project templates, see: http://aka.ms/winui-project-info.
|
// and more about our project templates, see: http://aka.ms/winui-project-info.
|
||||||
@@ -10,6 +15,23 @@ namespace Ghost.Editor
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class App : Application
|
public partial class App : Application
|
||||||
{
|
{
|
||||||
|
private Window? _window;
|
||||||
|
|
||||||
|
public IHost Host
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static T GetService<T>() where T : class
|
||||||
|
{
|
||||||
|
if ((Current as App)!.Host.Services.GetService(typeof(T)) is not T service)
|
||||||
|
{
|
||||||
|
throw new ArgumentException($"{typeof(T)} needs to be registered in ConfigureServices within App.xaml.cs.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return service;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes the singleton application object. This is the first line of authored code
|
/// Initializes the singleton application object. This is the first line of authored code
|
||||||
/// executed, and as such is the logical equivalent of main() or WinMain().
|
/// executed, and as such is the logical equivalent of main() or WinMain().
|
||||||
@@ -17,6 +39,16 @@ namespace Ghost.Editor
|
|||||||
public App()
|
public App()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
|
Host = Microsoft.Extensions.Hosting.Host.
|
||||||
|
CreateDefaultBuilder().
|
||||||
|
UseContentRoot(AppContext.BaseDirectory).
|
||||||
|
ConfigureServices((context, services) =>
|
||||||
|
{
|
||||||
|
services.AddTransient<LandingWindow>();
|
||||||
|
services.AddTransient<LandingViewModel>();
|
||||||
|
})
|
||||||
|
.Build();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -25,10 +57,11 @@ namespace Ghost.Editor
|
|||||||
/// <param name="args">Details about the launch request and process.</param>
|
/// <param name="args">Details about the launch request and process.</param>
|
||||||
protected override void OnLaunched(LaunchActivatedEventArgs args)
|
protected override void OnLaunched(LaunchActivatedEventArgs args)
|
||||||
{
|
{
|
||||||
m_window = new MainWindow();
|
base.OnLaunched(args);
|
||||||
m_window.Activate();
|
Host.Start();
|
||||||
}
|
|
||||||
|
|
||||||
private Window? m_window;
|
_window = GetService<LandingWindow>();
|
||||||
|
_window.Activate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -10,7 +10,12 @@
|
|||||||
<PublishProfile>win-$(Platform).pubxml</PublishProfile>
|
<PublishProfile>win-$(Platform).pubxml</PublishProfile>
|
||||||
<UseWinUI>true</UseWinUI>
|
<UseWinUI>true</UseWinUI>
|
||||||
<EnableMsixTooling>true</EnableMsixTooling>
|
<EnableMsixTooling>true</EnableMsixTooling>
|
||||||
|
<LangVersion>preview</LangVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Remove="View\Pages\Landing\CreateProjectPage.xaml" />
|
||||||
|
<None Remove="View\Pages\Landing\OpenProjectPage.xaml" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="Assets\SplashScreen.scale-200.png" />
|
<Content Include="Assets\SplashScreen.scale-200.png" />
|
||||||
@@ -41,8 +46,24 @@
|
|||||||
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.7.250310001" />
|
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.7.250310001" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Ghost.Database\Ghost.Database.csproj" />
|
||||||
<ProjectReference Include="..\Ghost.Engine\Ghost.Engine.csproj" />
|
<ProjectReference Include="..\Ghost.Engine\Ghost.Engine.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Page Update="View\Pages\Landing\CreateProjectPage.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Page Update="View\Window\Landing.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Page Update="View\Pages\Landing\OpenProjectPage.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Globals" />
|
<PropertyGroup Label="Globals" />
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Window
|
|
||||||
x:Class="Ghost.Editor.MainWindow"
|
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
||||||
xmlns:local="using:Ghost.Editor"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
||||||
mc:Ignorable="d"
|
|
||||||
Title="Ghost.Editor">
|
|
||||||
|
|
||||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
|
|
||||||
<Button x:Name="myButton" Click="myButton_Click">Click Me</Button>
|
|
||||||
</StackPanel>
|
|
||||||
</Window>
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Runtime.InteropServices.WindowsRuntime;
|
|
||||||
using Microsoft.UI.Xaml;
|
|
||||||
using Microsoft.UI.Xaml.Controls;
|
|
||||||
using Microsoft.UI.Xaml.Controls.Primitives;
|
|
||||||
using Microsoft.UI.Xaml.Data;
|
|
||||||
using Microsoft.UI.Xaml.Input;
|
|
||||||
using Microsoft.UI.Xaml.Media;
|
|
||||||
using Microsoft.UI.Xaml.Navigation;
|
|
||||||
using Windows.Foundation;
|
|
||||||
using Windows.Foundation.Collections;
|
|
||||||
|
|
||||||
// To learn more about WinUI, the WinUI project structure,
|
|
||||||
// and more about our project templates, see: http://aka.ms/winui-project-info.
|
|
||||||
|
|
||||||
namespace Ghost.Editor
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// An empty window that can be used on its own or navigated to within a Frame.
|
|
||||||
/// </summary>
|
|
||||||
public sealed partial class MainWindow : Window
|
|
||||||
{
|
|
||||||
public MainWindow()
|
|
||||||
{
|
|
||||||
this.InitializeComponent();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void myButton_Click(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
myButton.Content = "Clicked";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
41
Ghost.Editor/View/Pages/Landing/CreateProjectPage.xaml
Normal file
41
Ghost.Editor/View/Pages/Landing/CreateProjectPage.xaml
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<Page
|
||||||
|
x:Class="Ghost.Editor.View.Pages.Landing.CreateProjectPage"
|
||||||
|
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:data="using:Ghost.Database.Models.Projects"
|
||||||
|
xmlns:local="using:Ghost.Editor.View.Pages.Landing"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
mc:Ignorable="d">
|
||||||
|
|
||||||
|
<Grid>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<!-- Template Info -->
|
||||||
|
<Grid Grid.Column="0">
|
||||||
|
<TextBlock
|
||||||
|
Grid.Column="0"
|
||||||
|
Style="{StaticResource SubtitleTextBlockStyle}"
|
||||||
|
Text="Template" />
|
||||||
|
|
||||||
|
<ListView SelectedItem="">
|
||||||
|
<ListView.ItemTemplate>
|
||||||
|
<DataTemplate x:DataType="data:TemplateInfo">
|
||||||
|
<TextBlock VerticalAlignment="Center" Text="{x:Bind Name}" />
|
||||||
|
</DataTemplate>
|
||||||
|
</ListView.ItemTemplate>
|
||||||
|
</ListView>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<!-- Project Info -->
|
||||||
|
<Grid Grid.Column="1" DataContext="{x:Bind ViewModel.SelectedTemplate, Mode=OneWay}">
|
||||||
|
<Image Stretch="UniformToFill" />
|
||||||
|
<TextBlock Text="{x:Bind ViewModel.SelectedTemplate.Description}" />
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
</Page>
|
||||||
22
Ghost.Editor/View/Pages/Landing/CreateProjectPage.xaml.cs
Normal file
22
Ghost.Editor/View/Pages/Landing/CreateProjectPage.xaml.cs
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
using Ghost.Editor.ViewModel.Pages.Landing;
|
||||||
|
using Microsoft.UI.Xaml.Controls;
|
||||||
|
|
||||||
|
// To learn more about WinUI, the WinUI project structure,
|
||||||
|
// and more about our project templates, see: http://aka.ms/winui-project-info.
|
||||||
|
|
||||||
|
namespace Ghost.Editor.View.Pages.Landing;
|
||||||
|
|
||||||
|
internal sealed partial class CreateProjectPage : Page
|
||||||
|
{
|
||||||
|
public CreateProjectViewModel ViewModel
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CreateProjectPage(CreateProjectViewModel viewModel)
|
||||||
|
{
|
||||||
|
ViewModel = viewModel;
|
||||||
|
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
}
|
||||||
59
Ghost.Editor/View/Pages/Landing/OpenProjectPage.xaml
Normal file
59
Ghost.Editor/View/Pages/Landing/OpenProjectPage.xaml
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<Page
|
||||||
|
x:Class="Ghost.Editor.View.Pages.Landing.OpenProjectPage"
|
||||||
|
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:data="using:Ghost.Database.Models.Projects"
|
||||||
|
xmlns:local="using:Ghost.Editor.View.Pages.Landing"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
mc:Ignorable="d">
|
||||||
|
|
||||||
|
<Grid>
|
||||||
|
<ListView
|
||||||
|
x:Name="ProjectListView"
|
||||||
|
IsItemClickEnabled="True"
|
||||||
|
ItemClick="ListView_ItemClick"
|
||||||
|
ItemsSource="{x:Bind projects}"
|
||||||
|
Visibility="Visible">
|
||||||
|
<ListView.ItemTemplate>
|
||||||
|
<DataTemplate x:DataType="data:ProjectInfo">
|
||||||
|
<Grid>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<Grid Grid.Column="0">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="0"
|
||||||
|
Style="{StaticResource SubtitleTextBlockStyle}"
|
||||||
|
Text="{x:Bind Name}" />
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="1"
|
||||||
|
Style="{StaticResource BodyTextBlockStyle}"
|
||||||
|
Text="{x:Bind Path}" />
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<TextBlock Grid.Column="1" Text="{x:Bind LastOpened}" />
|
||||||
|
<TextBlock Grid.Column="2" Text="{x:Bind EngineVersion}" />
|
||||||
|
</Grid>
|
||||||
|
</DataTemplate>
|
||||||
|
</ListView.ItemTemplate>
|
||||||
|
</ListView>
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
x:Name="PlaceHolderText"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Style="{StaticResource TitleTextBlockStyle}"
|
||||||
|
Text="No projects found"
|
||||||
|
Visibility="Collapsed" />
|
||||||
|
</Grid>
|
||||||
|
</Page>
|
||||||
41
Ghost.Editor/View/Pages/Landing/OpenProjectPage.xaml.cs
Normal file
41
Ghost.Editor/View/Pages/Landing/OpenProjectPage.xaml.cs
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
using Ghost.Database.DataContext;
|
||||||
|
using Ghost.Database.Models.Projects;
|
||||||
|
using Microsoft.UI.Xaml;
|
||||||
|
using Microsoft.UI.Xaml.Controls;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
|
||||||
|
// To learn more about WinUI, the WinUI project structure,
|
||||||
|
// and more about our project templates, see: http://aka.ms/winui-project-info.
|
||||||
|
|
||||||
|
namespace Ghost.Editor.View.Pages.Landing;
|
||||||
|
|
||||||
|
internal sealed partial class OpenProjectPage : Page
|
||||||
|
{
|
||||||
|
public readonly ObservableCollection<ProjectInfo> projects = new();
|
||||||
|
|
||||||
|
public OpenProjectPage()
|
||||||
|
{
|
||||||
|
foreach (var project in ProjectRepository.LoadProjects())
|
||||||
|
{
|
||||||
|
projects.Add(project);
|
||||||
|
}
|
||||||
|
|
||||||
|
InitializeComponent();
|
||||||
|
|
||||||
|
if (projects.Count == 0)
|
||||||
|
{
|
||||||
|
PlaceHolderText.Visibility = Visibility.Visible;
|
||||||
|
ProjectListView.Visibility = Visibility.Collapsed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ListView_ItemClick(object sender, ItemClickEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.ClickedItem is not ProjectInfo project)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: Load project
|
||||||
|
}
|
||||||
|
}
|
||||||
40
Ghost.Editor/View/Windows/LandingWindow.xaml
Normal file
40
Ghost.Editor/View/Windows/LandingWindow.xaml
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<Window
|
||||||
|
x:Class="Ghost.Editor.View.Windows.LandingWindow"
|
||||||
|
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:local="using:Ghost.Editor.View.Windows"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
Title="Landing"
|
||||||
|
mc:Ignorable="d">
|
||||||
|
|
||||||
|
<Grid Padding="4">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="*" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<SelectorBar
|
||||||
|
Grid.Row="0"
|
||||||
|
HorizontalAlignment="Right"
|
||||||
|
SelectionChanged="SelectorBar_SelectionChanged">
|
||||||
|
<SelectorBarItem IsSelected="True" Text="Open">
|
||||||
|
<SelectorBarItem.Icon>
|
||||||
|
<FontIcon Glyph="" />
|
||||||
|
</SelectorBarItem.Icon>
|
||||||
|
</SelectorBarItem>
|
||||||
|
<SelectorBarItem Text="Create">
|
||||||
|
<SelectorBarItem.Icon>
|
||||||
|
<FontIcon Glyph="" />
|
||||||
|
</SelectorBarItem.Icon>
|
||||||
|
</SelectorBarItem>
|
||||||
|
</SelectorBar>
|
||||||
|
|
||||||
|
<Frame
|
||||||
|
x:Name="ContentFrame"
|
||||||
|
Grid.Row="1"
|
||||||
|
Padding="24,8"
|
||||||
|
IsNavigationStackEnabled="False" />
|
||||||
|
</Grid>
|
||||||
|
</Window>
|
||||||
47
Ghost.Editor/View/Windows/LandingWindow.xaml.cs
Normal file
47
Ghost.Editor/View/Windows/LandingWindow.xaml.cs
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
// To learn more about WinUI, the WinUI project structure,
|
||||||
|
// and more about our project templates, see: http://aka.ms/winui-project-info.
|
||||||
|
|
||||||
|
using Ghost.Editor.View.Pages.Landing;
|
||||||
|
using Ghost.Editor.ViewModel.Windows;
|
||||||
|
using Microsoft.UI.Xaml;
|
||||||
|
using Microsoft.UI.Xaml.Controls;
|
||||||
|
using Microsoft.UI.Xaml.Media.Animation;
|
||||||
|
|
||||||
|
namespace Ghost.Editor.View.Windows;
|
||||||
|
|
||||||
|
internal sealed partial class LandingWindow : Window
|
||||||
|
{
|
||||||
|
public LandingViewModel ViewModel
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int _previousSelectedIndex;
|
||||||
|
|
||||||
|
public LandingWindow(LandingViewModel viewModel)
|
||||||
|
{
|
||||||
|
ViewModel = viewModel;
|
||||||
|
|
||||||
|
InitializeComponent();
|
||||||
|
|
||||||
|
AppWindow.Resize(new(1200, 900));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SelectorBar_SelectionChanged(SelectorBar sender, SelectorBarSelectionChangedEventArgs e)
|
||||||
|
{
|
||||||
|
var selectedItem = sender.SelectedItem;
|
||||||
|
var currentSelectedIndex = sender.Items.IndexOf(selectedItem);
|
||||||
|
var pageType = currentSelectedIndex switch
|
||||||
|
{
|
||||||
|
1 => typeof(CreateProjectPage),
|
||||||
|
_ => typeof(OpenProjectPage),
|
||||||
|
};
|
||||||
|
|
||||||
|
var slideNavigationTransitionEffect = currentSelectedIndex - _previousSelectedIndex > 0 ?
|
||||||
|
SlideNavigationTransitionEffect.FromRight : SlideNavigationTransitionEffect.FromLeft;
|
||||||
|
|
||||||
|
ContentFrame.Navigate(pageType, null, new SlideNavigationTransitionInfo() { Effect = slideNavigationTransitionEffect });
|
||||||
|
|
||||||
|
_previousSelectedIndex = currentSelectedIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
using Ghost.Database.Models.Projects;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
|
||||||
|
namespace Ghost.Editor.ViewModel.Pages.Landing;
|
||||||
|
|
||||||
|
internal partial class CreateProjectViewModel : ObservableRecipient
|
||||||
|
{
|
||||||
|
public ObservableCollection<TemplateInfo> templates = new();
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
public partial TemplateInfo SelectedTemplate
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
}
|
||||||
13
Ghost.Editor/ViewModel/Windows/LandingViewModel.cs
Normal file
13
Ghost.Editor/ViewModel/Windows/LandingViewModel.cs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
|
||||||
|
namespace Ghost.Editor.ViewModel.Windows;
|
||||||
|
|
||||||
|
internal partial class LandingViewModel : ObservableRecipient
|
||||||
|
{
|
||||||
|
[ObservableProperty]
|
||||||
|
public partial int TabIndex
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
}
|
||||||
3
Ghost.Engine/AssemblyInfo.cs
Normal file
3
Ghost.Engine/AssemblyInfo.cs
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
|
[assembly: InternalsVisibleTo("Ghost.Editor")]
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
namespace Ghost.Engine;
|
|
||||||
|
|
||||||
public class Class1
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -7,6 +7,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ghost.Editor", "Ghost.Edito
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ghost.Engine", "Ghost.Engine\Ghost.Engine.csproj", "{1ED62E09-8F36-4671-896B-16C1C1530202}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ghost.Engine", "Ghost.Engine\Ghost.Engine.csproj", "{1ED62E09-8F36-4671-896B-16C1C1530202}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ghost.Database", "Ghost.Database\Ghost.Database.csproj", "{0D626DAF-EF18-435C-A85C-EEA1B141E8B5}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|ARM64 = Debug|ARM64
|
Debug|ARM64 = Debug|ARM64
|
||||||
@@ -47,6 +49,18 @@ Global
|
|||||||
{1ED62E09-8F36-4671-896B-16C1C1530202}.Release|x64.Build.0 = Release|Any CPU
|
{1ED62E09-8F36-4671-896B-16C1C1530202}.Release|x64.Build.0 = Release|Any CPU
|
||||||
{1ED62E09-8F36-4671-896B-16C1C1530202}.Release|x86.ActiveCfg = Release|Any CPU
|
{1ED62E09-8F36-4671-896B-16C1C1530202}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
{1ED62E09-8F36-4671-896B-16C1C1530202}.Release|x86.Build.0 = Release|Any CPU
|
{1ED62E09-8F36-4671-896B-16C1C1530202}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{0D626DAF-EF18-435C-A85C-EEA1B141E8B5}.Debug|ARM64.ActiveCfg = Debug|Any CPU
|
||||||
|
{0D626DAF-EF18-435C-A85C-EEA1B141E8B5}.Debug|ARM64.Build.0 = Debug|Any CPU
|
||||||
|
{0D626DAF-EF18-435C-A85C-EEA1B141E8B5}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{0D626DAF-EF18-435C-A85C-EEA1B141E8B5}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{0D626DAF-EF18-435C-A85C-EEA1B141E8B5}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{0D626DAF-EF18-435C-A85C-EEA1B141E8B5}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{0D626DAF-EF18-435C-A85C-EEA1B141E8B5}.Release|ARM64.ActiveCfg = Release|Any CPU
|
||||||
|
{0D626DAF-EF18-435C-A85C-EEA1B141E8B5}.Release|ARM64.Build.0 = Release|Any CPU
|
||||||
|
{0D626DAF-EF18-435C-A85C-EEA1B141E8B5}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{0D626DAF-EF18-435C-A85C-EEA1B141E8B5}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{0D626DAF-EF18-435C-A85C-EEA1B141E8B5}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{0D626DAF-EF18-435C-A85C-EEA1B141E8B5}.Release|x86.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
Reference in New Issue
Block a user