- tweak: Dependency injection think
This commit is contained in:
1
.idea/.idea.Nebula/.idea/.name
generated
Normal file
1
.idea/.idea.Nebula/.idea/.name
generated
Normal file
@@ -0,0 +1 @@
|
||||
Nebula
|
||||
2
.idea/.idea.Nebula/.idea/avalonia.xml
generated
2
.idea/.idea.Nebula/.idea/avalonia.xml
generated
@@ -7,7 +7,9 @@
|
||||
<entry key="Nebula.Launcher/ViewModels/Styles1.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
|
||||
<entry key="Nebula.Launcher/Views/Controls/PlayerContainerControl.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
|
||||
<entry key="Nebula.Launcher/Views/Controls/ServerContainerControl.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
|
||||
<entry key="Nebula.Launcher/Views/MainView.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
|
||||
<entry key="Nebula.Launcher/Views/MainWindow.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
|
||||
<entry key="Nebula.Launcher/Views/Pages/AccountInfoPage.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
|
||||
<entry key="Nebula.Launcher/Views/ServerContainer.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
|
||||
<entry key="Nebula.Launcher/Views/ServerList.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
|
||||
<entry key="Nebula.Launcher/Views/Tabs/AccountInfoTab.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
|
||||
|
||||
@@ -1,46 +1,60 @@
|
||||
<Application xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
x:Class="Nebula.Launcher.App"
|
||||
xmlns:local="using:Nebula.Launcher"
|
||||
RequestedThemeVariant="Default">
|
||||
<!-- "Default" ThemeVariant follows system theme variant. "Dark" or "Light" are other available options. -->
|
||||
<Application
|
||||
RequestedThemeVariant="Default"
|
||||
x:Class="Nebula.Launcher.App"
|
||||
xmlns="https://github.com/avaloniaui"
|
||||
xmlns:local="using:Nebula.Launcher"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
|
||||
<Application.DataTemplates>
|
||||
<local:ViewLocator/>
|
||||
<local:ViewLocator />
|
||||
</Application.DataTemplates>
|
||||
|
||||
|
||||
<Application.Styles>
|
||||
<FluentTheme />
|
||||
<Style Selector="Window">
|
||||
<Setter Property="Background" Value="#121212"/>
|
||||
<Setter Property="Background" Value="#121212" />
|
||||
</Style>
|
||||
<Style Selector="Border">
|
||||
<Setter Property="BorderBrush" Value="#343334"/>
|
||||
<Setter Property="Background" Value="#222222"/>
|
||||
<Setter Property="BorderBrush" Value="#343334" />
|
||||
<Setter Property="Background" Value="#222222" />
|
||||
<Setter Property="BorderThickness" Value="0" />
|
||||
</Style>
|
||||
<Style Selector="TextBlock">
|
||||
<Setter Property="Foreground" Value="#f7f7ff"/>
|
||||
<Setter Property="FontSize" Value="14"/>
|
||||
<Style Selector="Label">
|
||||
<Setter Property="Foreground" Value="#f7f7ff" />
|
||||
</Style>
|
||||
|
||||
|
||||
<Style Selector="Button">
|
||||
<Setter Property="Background" Value="#e63462"/>
|
||||
<Setter Property="BorderBrush" Value="#343334"/>
|
||||
<Setter Property="Padding" Value="5"/>
|
||||
<Setter Property="CornerRadius" Value="10"/>
|
||||
<Setter Property="BorderBrush" Value="#343334" />
|
||||
<Setter Property="BorderThickness" Value="0" />
|
||||
<Setter Property="Padding" Value="5" />
|
||||
<Setter Property="CornerRadius" Value="10" />
|
||||
</Style>
|
||||
|
||||
|
||||
<Style Selector="Button:pressed">
|
||||
<Setter Property="Background" Value="#b82a4e"/>
|
||||
<Setter Property="RenderTransform" Value="{x:Null}" />
|
||||
</Style>
|
||||
|
||||
|
||||
<Style Selector="Border.ButtonBack">
|
||||
<Setter Property="Background" Value="#e63462" />
|
||||
<Setter Property="CornerRadius" Value="0,0,10,0" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="Button.ViewSelectButton">
|
||||
<Setter Property="CornerRadius" Value="0,8,8,0"/>
|
||||
<Setter Property="Margin" Value="0,0,0,5"/>
|
||||
<Setter Property="Padding" Value="8"/>
|
||||
<Setter Property="Background" Value="#00000000"/>
|
||||
<Setter Property="CornerRadius" Value="0,8,8,0" />
|
||||
<Setter Property="Margin" Value="0,0,0,5" />
|
||||
<Setter Property="Padding" Value="8" />
|
||||
<Setter Property="Background" Value="#00000000" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="Button.ViewSelectButton:pressed">
|
||||
<Setter Property="Background" Value="#e63462"/>
|
||||
<Setter Property="BorderThickness" Value="0,0,0,0" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="TextBox">
|
||||
<Setter Property="Foreground" Value="#f7f7ff" />
|
||||
<Setter Property="SelectionForegroundBrush" Value="#f7f7ff" />
|
||||
<Setter Property="BorderThickness" Value="0,0,0,1" />
|
||||
<Setter Property="BorderBrush" Value="#f7f7ff" />
|
||||
</Style>
|
||||
</Application.Styles>
|
||||
</Application>
|
||||
@@ -1,9 +1,11 @@
|
||||
using System;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls.ApplicationLifetimes;
|
||||
using Avalonia.Data.Core;
|
||||
using Avalonia.Data.Core.Plugins;
|
||||
using System.Linq;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Nebula.Launcher.ViewModels;
|
||||
using Nebula.Launcher.Views;
|
||||
|
||||
@@ -11,6 +13,8 @@ namespace Nebula.Launcher;
|
||||
|
||||
public partial class App : Application
|
||||
{
|
||||
private IServiceProvider _serviceProvider = null!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
@@ -18,10 +22,20 @@ public partial class App : Application
|
||||
|
||||
public override void OnFrameworkInitializationCompleted()
|
||||
{
|
||||
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||
var services = new ServiceCollection();
|
||||
services.AddServices();
|
||||
|
||||
_serviceProvider = services.BuildServiceProvider();
|
||||
|
||||
switch (ApplicationLifetime)
|
||||
{
|
||||
DisableAvaloniaDataAnnotationValidation();
|
||||
desktop.MainWindow = new MainWindow();
|
||||
case IClassicDesktopStyleApplicationLifetime desktop:
|
||||
DisableAvaloniaDataAnnotationValidation();
|
||||
desktop.MainWindow = _serviceProvider.GetService<MainWindow>();
|
||||
break;
|
||||
case ISingleViewApplicationLifetime singleViewPlatform:
|
||||
singleViewPlatform.MainView = _serviceProvider.GetRequiredService<MainView>();
|
||||
break;
|
||||
}
|
||||
|
||||
base.OnFrameworkInitializationCompleted();
|
||||
|
||||
21
Nebula.Launcher/Converters/TypeConverters.cs
Normal file
21
Nebula.Launcher/Converters/TypeConverters.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Data.Converters;
|
||||
using Avalonia.Media;
|
||||
|
||||
namespace Nebula.Launcher.Converters;
|
||||
|
||||
public class TypeConverters
|
||||
{
|
||||
private const string StreamGeometryNotFound =
|
||||
"M24 4C35.0457 4 44 12.9543 44 24C44 35.0457 35.0457 44 24 44C12.9543 44 4 35.0457 4 24C4 12.9543 12.9543 4 24 4ZM24 6.5C14.335 6.5 6.5 14.335 6.5 24C6.5 33.665 14.335 41.5 24 41.5C33.665 41.5 41.5 33.665 41.5 24C41.5 14.335 33.665 6.5 24 6.5ZM24.25 32C25.0784 32 25.75 32.6716 25.75 33.5C25.75 34.3284 25.0784 35 24.25 35C23.4216 35 22.75 34.3284 22.75 33.5C22.75 32.6716 23.4216 32 24.25 32ZM24.25 13C27.6147 13 30.5 15.8821 30.5 19.2488C30.502 21.3691 29.7314 22.7192 27.8216 24.7772L26.8066 25.8638C25.7842 27.0028 25.3794 27.7252 25.3409 28.5793L25.3379 28.7411L25.3323 28.8689L25.3143 28.9932C25.2018 29.5636 24.7009 29.9957 24.0968 30.0001C23.4065 30.0049 22.8428 29.4493 22.8379 28.7589C22.8251 26.9703 23.5147 25.7467 25.1461 23.9739L26.1734 22.8762C27.5312 21.3837 28.0012 20.503 28 19.25C28 17.2634 26.2346 15.5 24.25 15.5C22.3307 15.5 20.6142 17.1536 20.5055 19.0587L20.4935 19.3778C20.4295 20.0081 19.8972 20.5 19.25 20.5C18.5596 20.5 18 19.9404 18 19.25C18 15.8846 20.8864 13 24.25 13Z";
|
||||
|
||||
public static FuncValueConverter<string, StreamGeometry> IconConverter { get; } =
|
||||
new(iconKey =>
|
||||
{
|
||||
if (iconKey is null) return StreamGeometry.Parse(StreamGeometryNotFound);
|
||||
|
||||
Application.Current!.TryFindResource(iconKey, out var resource);
|
||||
return resource as StreamGeometry ?? StreamGeometry.Parse(StreamGeometryNotFound);
|
||||
});
|
||||
}
|
||||
4
Nebula.Launcher/Models/ListItemTemplate.cs
Normal file
4
Nebula.Launcher/Models/ListItemTemplate.cs
Normal file
@@ -0,0 +1,4 @@
|
||||
using System;
|
||||
|
||||
namespace Nebula.Launcher.Models;
|
||||
public record ListItemTemplate(Type ModelType, string IconKey, string Label);
|
||||
@@ -9,7 +9,6 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Models\" />
|
||||
<AvaloniaResource Include="Assets\**" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -17,7 +16,6 @@
|
||||
<PackageReference Include="AsyncImageLoader.Avalonia" Version="3.3.0" />
|
||||
<PackageReference Include="Avalonia" Version="11.2.1" />
|
||||
<PackageReference Include="Avalonia.Desktop" Version="11.2.1" />
|
||||
<PackageReference Include="Avalonia.ReactiveUI" Version="11.2.1" />
|
||||
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.2.1" />
|
||||
<PackageReference Include="Avalonia.Fonts.Inter" Version="11.2.1" />
|
||||
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
|
||||
@@ -26,6 +24,7 @@
|
||||
<PrivateAssets Condition="'$(Configuration)' != 'Debug'">All</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using Avalonia;
|
||||
using System;
|
||||
using Avalonia.ReactiveUI;
|
||||
|
||||
namespace Nebula.Launcher;
|
||||
|
||||
@@ -18,6 +17,5 @@ sealed class Program
|
||||
=> AppBuilder.Configure<App>()
|
||||
.UsePlatformDetect()
|
||||
.WithInterFont()
|
||||
.UseReactiveUI()
|
||||
.LogToTrace();
|
||||
}
|
||||
52
Nebula.Launcher/ServiceCollectionExtensions.cs
Normal file
52
Nebula.Launcher/ServiceCollectionExtensions.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
using System;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.ApplicationLifetimes;
|
||||
using Avalonia.Threading;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Nebula.Launcher.ViewModels;
|
||||
using Nebula.Launcher.Views;
|
||||
using Nebula.Launcher.Views.Pages;
|
||||
|
||||
namespace Nebula.Launcher;
|
||||
|
||||
public static class ServiceCollectionExtensions
|
||||
{
|
||||
public static void AddServices(this IServiceCollection services)
|
||||
{
|
||||
services.AddAvaloniaServices();
|
||||
services.AddViews();
|
||||
}
|
||||
|
||||
private static void AddAvaloniaServices(this IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<IDispatcher>(_ => Dispatcher.UIThread);
|
||||
services.AddSingleton(_ => Application.Current?.ApplicationLifetime ?? throw new InvalidOperationException("No application lifetime is set"));
|
||||
|
||||
services.AddSingleton(sp =>
|
||||
sp.GetRequiredService<IApplicationLifetime>() switch
|
||||
{
|
||||
IClassicDesktopStyleApplicationLifetime desktop => desktop.MainWindow ?? throw new InvalidOperationException("No main window set"),
|
||||
ISingleViewApplicationLifetime singleViewPlatform => TopLevel.GetTopLevel(singleViewPlatform.MainView) ?? throw new InvalidOperationException("Could not find top level element for single view"),
|
||||
_ => throw new InvalidOperationException($"Could not find {nameof(TopLevel)} element"),
|
||||
}
|
||||
);
|
||||
|
||||
services.AddSingleton(sp => sp.GetRequiredService<TopLevel>().StorageProvider);
|
||||
}
|
||||
|
||||
private static void AddViews(this IServiceCollection services)
|
||||
{
|
||||
services.AddTransient<MainWindow>();
|
||||
services.AddView<MainView, MainViewModel>();
|
||||
services.AddView<AccountInfoPage, AccountInfoViewModel>();
|
||||
}
|
||||
|
||||
private static void AddView<TView, TViewModel>(this IServiceCollection services)
|
||||
where TView : class
|
||||
where TViewModel : class
|
||||
{
|
||||
services.AddTransient<TViewModel>();
|
||||
services.AddTransient<TView>();
|
||||
}
|
||||
}
|
||||
8
Nebula.Launcher/ViewModels/AccountInfoViewModel.cs
Normal file
8
Nebula.Launcher/ViewModels/AccountInfoViewModel.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using Nebula.Launcher.Views.Pages;
|
||||
|
||||
namespace Nebula.Launcher.ViewModels;
|
||||
|
||||
public class AccountInfoViewModel : ViewModelBase, ITab
|
||||
{
|
||||
|
||||
}
|
||||
63
Nebula.Launcher/ViewModels/MainViewModel.cs
Normal file
63
Nebula.Launcher/ViewModels/MainViewModel.cs
Normal file
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using Avalonia.Controls;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Nebula.Launcher.Models;
|
||||
|
||||
namespace Nebula.Launcher.ViewModels;
|
||||
|
||||
|
||||
public partial class MainViewModel : ViewModelBase
|
||||
{
|
||||
public MainViewModel(AccountInfoViewModel accountInfoViewModel, IServiceProvider serviceProvider)
|
||||
{
|
||||
_currentPage = accountInfoViewModel;
|
||||
_serviceProvider = serviceProvider;
|
||||
Items = new ObservableCollection<ListItemTemplate>(_templates);
|
||||
|
||||
SelectedListItem = Items.First(vm => vm.ModelType == typeof(AccountInfoViewModel));
|
||||
}
|
||||
|
||||
private readonly List<ListItemTemplate> _templates =
|
||||
[
|
||||
new ListItemTemplate(typeof(AccountInfoViewModel), "HomeRegular", "Account"),
|
||||
];
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isPaneOpen;
|
||||
|
||||
[ObservableProperty]
|
||||
private ViewModelBase _currentPage;
|
||||
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
|
||||
[ObservableProperty]
|
||||
private ListItemTemplate? _selectedListItem;
|
||||
|
||||
partial void OnSelectedListItemChanged(ListItemTemplate? value)
|
||||
{
|
||||
if (value is null) return;
|
||||
|
||||
var vm = Design.IsDesignMode
|
||||
? Activator.CreateInstance(value.ModelType)
|
||||
: _serviceProvider.GetService(value.ModelType);
|
||||
|
||||
if (vm is not ViewModelBase vmb) return;
|
||||
|
||||
CurrentPage = vmb;
|
||||
}
|
||||
|
||||
public ObservableCollection<ListItemTemplate> Items { get; }
|
||||
|
||||
[RelayCommand]
|
||||
private void TriggerPane()
|
||||
{
|
||||
IsPaneOpen = !IsPaneOpen;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
using System;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Nebula.Launcher.ViewModels;
|
||||
|
||||
public sealed class TestViewModel : ViewModelBase
|
||||
{
|
||||
private string _greeting = "Welcome to Avalonia!";
|
||||
|
||||
public string Greeting
|
||||
{
|
||||
get => _greeting;
|
||||
set => this.RaiseAndSetIfChanged(ref _greeting, value);
|
||||
}
|
||||
|
||||
public void ButtonAction()
|
||||
{
|
||||
Console.WriteLine("HAS");
|
||||
Greeting = "Another greeting from Avalonia";
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
using ReactiveUI;
|
||||
using Avalonia.Controls;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
|
||||
namespace Nebula.Launcher.ViewModels;
|
||||
|
||||
public abstract class ViewModelBase : ReactiveObject
|
||||
public abstract class ViewModelBase : ObservableObject
|
||||
{
|
||||
}
|
||||
@@ -1,19 +1,36 @@
|
||||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="Nebula.Launcher.Views.Controls.PlayerContainerControl">
|
||||
<Border Margin="5,4,5,0"
|
||||
CornerRadius="0,10,0,10" BorderThickness="0,1,1,0" VerticalAlignment="Center">
|
||||
<UserControl
|
||||
d:DesignHeight="450"
|
||||
d:DesignWidth="800"
|
||||
mc:Ignorable="d"
|
||||
x:Class="Nebula.Launcher.Views.Controls.PlayerContainerControl"
|
||||
xmlns="https://github.com/avaloniaui"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
<Border
|
||||
BorderThickness="0,0,1,0"
|
||||
CornerRadius="0,10,0,10"
|
||||
Margin="5,4,5,0"
|
||||
VerticalAlignment="Center">
|
||||
<Panel>
|
||||
<StackPanel Orientation="Horizontal" Margin="5">
|
||||
<TextBlock Margin="0,0,2,0">Name:</TextBlock>
|
||||
<TextBlock>Ni Higgers</TextBlock>
|
||||
<StackPanel Margin="10,5,5,5" Orientation="Horizontal">
|
||||
<Label Margin="0,0,2,0">Name:</Label>
|
||||
<Label>Ni Higgers</Label>
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
|
||||
<Button Padding="5" CornerRadius="0,0,0,10">Select</Button>
|
||||
<Button Padding="5" BorderThickness="2,0,0,0" CornerRadius="0,10,0,0">Delete</Button>
|
||||
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
|
||||
<Button CornerRadius="0,0,0,10" Padding="5">
|
||||
<Label>
|
||||
Select
|
||||
</Label>
|
||||
</Button>
|
||||
<Button
|
||||
BorderThickness="2,0,0,0"
|
||||
CornerRadius="0,10,0,0"
|
||||
Padding="5">
|
||||
<Label>
|
||||
Delete
|
||||
</Label>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</Panel>
|
||||
</Border>
|
||||
|
||||
@@ -1,36 +1,57 @@
|
||||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:asyncImageLoader="clr-namespace:AsyncImageLoader;assembly=AsyncImageLoader.Avalonia"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="Nebula.Launcher.Views.Controls.ServerContainerControl">
|
||||
<Grid ColumnDefinitions="*,70" RowDefinitions="*,*" Margin="0,5,0,5">
|
||||
<Border Grid.Row="0" Grid.Column="0" BorderThickness="2,0,0,0"
|
||||
Padding="10">
|
||||
<TextBlock>Server name</TextBlock>
|
||||
<UserControl
|
||||
d:DesignHeight="100"
|
||||
d:DesignWidth="800"
|
||||
mc:Ignorable="d"
|
||||
x:Class="Nebula.Launcher.Views.Controls.ServerContainerControl"
|
||||
xmlns="https://github.com/avaloniaui"
|
||||
xmlns:asyncImageLoader="clr-namespace:AsyncImageLoader;assembly=AsyncImageLoader.Avalonia"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
<Grid
|
||||
ColumnDefinitions="*,70"
|
||||
Margin="0,5,0,5"
|
||||
RowDefinitions="40,*">
|
||||
<Border
|
||||
BorderThickness="2,0,0,0"
|
||||
Grid.Column="0"
|
||||
Grid.Row="0"
|
||||
Padding="10">
|
||||
<Label>Server name</Label>
|
||||
</Border>
|
||||
<Border Grid.Row="0" Grid.Column="1"
|
||||
BorderThickness="2,0,0,0"
|
||||
CornerRadius="0"
|
||||
Padding="5">
|
||||
<TextBlock HorizontalAlignment="Center">15/15</TextBlock>
|
||||
<Border
|
||||
BorderThickness="2,0,0,0"
|
||||
CornerRadius="0"
|
||||
Grid.Column="1"
|
||||
Grid.Row="0"
|
||||
Padding="5">
|
||||
<Label HorizontalAlignment="Center" VerticalAlignment="Center">15/15</Label>
|
||||
</Border>
|
||||
|
||||
<Border Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" BorderThickness="2,0,0,0"
|
||||
Height="50"
|
||||
CornerRadius="0,0,10,10">
|
||||
|
||||
<Border
|
||||
BorderThickness="2,0,0,0"
|
||||
CornerRadius="0,0,10,10"
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="2"
|
||||
Grid.Row="1"
|
||||
MinHeight="50">
|
||||
<Border.Background>
|
||||
<ImageBrush Stretch="UniformToFill"
|
||||
asyncImageLoader:ImageBrushLoader.Source="https://t4.ftcdn.net/jpg/00/81/55/69/360_F_81556974_8sF8cKszJaRfBGd5sDt1RXE2QbzDtQqs.jpg">
|
||||
</ImageBrush>
|
||||
<ImageBrush Stretch="UniformToFill" asyncImageLoader:ImageBrushLoader.Source="https://t4.ftcdn.net/jpg/00/81/55/69/360_F_81556974_8sF8cKszJaRfBGd5sDt1RXE2QbzDtQqs.jpg" />
|
||||
</Border.Background>
|
||||
</Border>
|
||||
|
||||
<Panel Grid.Row="1" Grid.Column="1">
|
||||
<Button VerticalAlignment="Stretch" CornerRadius="0 0 10 0" BorderThickness="0,0,0,0">
|
||||
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5">Play</TextBlock>
|
||||
</Button>
|
||||
|
||||
<Panel Grid.Column="1" Grid.Row="1">
|
||||
<Border Classes="ButtonBack" CornerRadius="0,0,10,0">
|
||||
<Button
|
||||
CornerRadius="0,0,10,0"
|
||||
HorizontalAlignment="Stretch"
|
||||
Padding="0"
|
||||
VerticalAlignment="Stretch">
|
||||
<Label HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||
Play
|
||||
</Label>
|
||||
</Button>
|
||||
</Border>
|
||||
</Panel>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
||||
70
Nebula.Launcher/Views/MainView.axaml
Normal file
70
Nebula.Launcher/Views/MainView.axaml
Normal file
@@ -0,0 +1,70 @@
|
||||
<UserControl
|
||||
d:DesignHeight="450"
|
||||
d:DesignWidth="800"
|
||||
mc:Ignorable="d"
|
||||
x:Class="Nebula.Launcher.Views.MainView"
|
||||
x:DataType="viewModels:MainViewModel"
|
||||
xmlns="https://github.com/avaloniaui"
|
||||
xmlns:converters="clr-namespace:Nebula.Launcher.Converters"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:models="clr-namespace:Nebula.Launcher.Models"
|
||||
xmlns:viewModels="clr-namespace:Nebula.Launcher.ViewModels"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
|
||||
<Grid
|
||||
ColumnDefinitions="*"
|
||||
Margin="0"
|
||||
RowDefinitions="*,40">
|
||||
<SplitView
|
||||
CompactPaneLength="65"
|
||||
DisplayMode="CompactInline"
|
||||
IsPaneOpen="{Binding IsPaneOpen}"
|
||||
PaneBackground="#00000000">
|
||||
<SplitView.Pane>
|
||||
<Border
|
||||
BorderThickness="0,0,2,0"
|
||||
CornerRadius="0,8,8,0"
|
||||
Grid.Column="0"
|
||||
Grid.Row="0"
|
||||
Margin="0,0,5,0"
|
||||
Padding="0">
|
||||
<ListBox
|
||||
ItemsSource="{Binding Items}"
|
||||
Margin="2,0,-100,0"
|
||||
Padding="0"
|
||||
SelectedItem="{Binding SelectedListItem}">
|
||||
<ListBox.Styles>
|
||||
<Style Selector="ListBoxItem">
|
||||
<Setter Property="Padding" Value="12 8" />
|
||||
</Style>
|
||||
</ListBox.Styles>
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate DataType="{x:Type models:ListItemTemplate}">
|
||||
<StackPanel Orientation="Horizontal" Spacing="17">
|
||||
<PathIcon Data="{Binding IconKey, Converter={x:Static converters:TypeConverters.IconConverter}}" Width="14" />
|
||||
<TextBlock Text="{Binding Label}">
|
||||
<TextBlock.IsVisible />
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
</Border>
|
||||
</SplitView.Pane>
|
||||
</SplitView>
|
||||
|
||||
|
||||
<Border
|
||||
BorderThickness="0,2,0,0"
|
||||
CornerRadius="0,0,0,0"
|
||||
Grid.Row="1"
|
||||
Margin="0,0,0,0"
|
||||
Padding="5">
|
||||
<Panel>
|
||||
<Label HorizontalAlignment="Left" VerticalAlignment="Center">cinka.ru</Label>
|
||||
<Label HorizontalAlignment="Right" VerticalAlignment="Center">v0.01</Label>
|
||||
</Panel>
|
||||
</Border>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
25
Nebula.Launcher/Views/MainView.axaml.cs
Normal file
25
Nebula.Launcher/Views/MainView.axaml.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.Windows.Input;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Nebula.Launcher.ViewModels;
|
||||
|
||||
namespace Nebula.Launcher.Views;
|
||||
|
||||
public partial class MainView : UserControl
|
||||
{
|
||||
|
||||
// This constructor is used when the view is created by the XAML Previewer
|
||||
public MainView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
// This constructor is used when the view is created via dependency injection
|
||||
public MainView(MainViewModel viewModel)
|
||||
: this()
|
||||
{
|
||||
DataContext = viewModel;
|
||||
}
|
||||
}
|
||||
@@ -1,54 +1,15 @@
|
||||
<Window xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:vm="using:Nebula.Launcher.ViewModels"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:tabs="clr-namespace:Nebula.Launcher.Views.Tabs"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="Nebula.Launcher.Views.MainWindow"
|
||||
x:DataType="vm:TestViewModel"
|
||||
MinHeight="400"
|
||||
MinWidth="600"
|
||||
Height="400"
|
||||
Width="800"
|
||||
Icon="/Assets/avalonia-logo.ico"
|
||||
Title="Nebula.Launcher">
|
||||
|
||||
<Grid ColumnDefinitions="60,*" RowDefinitions="*,40" Margin="0">
|
||||
<Border Grid.Row="0" Grid.Column="0"
|
||||
BorderThickness="0,0,2,0"
|
||||
CornerRadius="0,8,8,0"
|
||||
Padding="0" Margin="0,0,5,0">
|
||||
<StackPanel>
|
||||
<Button Classes="ViewSelectButton">
|
||||
<Image Source="../Assets/account.png"/>
|
||||
</Button>
|
||||
<Button Classes="ViewSelectButton">
|
||||
<Image Source="../Assets/list.png"/>
|
||||
</Button>
|
||||
<Button Classes="ViewSelectButton" Padding="15">
|
||||
<Image Source="../Assets/settings.png"/>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<ScrollViewer Grid.Column="1" Grid.Row="0"
|
||||
HorizontalScrollBarVisibility="Visible"
|
||||
VerticalScrollBarVisibility="Disabled"
|
||||
Padding="5">
|
||||
<tabs:AccountInfoTab/>
|
||||
</ScrollViewer>
|
||||
|
||||
<Border Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2"
|
||||
BorderThickness="0,2,0,0"
|
||||
CornerRadius="0,0,0,0"
|
||||
Padding="5"
|
||||
Margin="0,0,0,0">
|
||||
<Panel>
|
||||
<TextBlock HorizontalAlignment="Left" VerticalAlignment="Center">cinka.ru</TextBlock>
|
||||
<TextBlock HorizontalAlignment="Right" VerticalAlignment="Center">v0.01</TextBlock>
|
||||
</Panel>
|
||||
</Border>
|
||||
</Grid>
|
||||
|
||||
</Window>
|
||||
<Window
|
||||
Height="400"
|
||||
Icon="/Assets/avalonia-logo.ico"
|
||||
MinHeight="400"
|
||||
MinWidth="600"
|
||||
Title="Nebula.Launcher"
|
||||
Width="800"
|
||||
d:DesignHeight="450"
|
||||
d:DesignWidth="800"
|
||||
mc:Ignorable="d"
|
||||
x:Class="Nebula.Launcher.Views.MainWindow"
|
||||
xmlns="https://github.com/avaloniaui"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" />
|
||||
|
||||
@@ -4,8 +4,16 @@ namespace Nebula.Launcher.Views;
|
||||
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
// This constructor is used when the view is created by the XAML Previewer
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
// This constructor is used when the view is created via dependency injection
|
||||
public MainWindow(MainView mainView)
|
||||
: this()
|
||||
{
|
||||
Content = mainView;
|
||||
}
|
||||
}
|
||||
59
Nebula.Launcher/Views/Pages/AccountInfoPage.axaml
Normal file
59
Nebula.Launcher/Views/Pages/AccountInfoPage.axaml
Normal file
@@ -0,0 +1,59 @@
|
||||
<UserControl
|
||||
d:DesignHeight="450"
|
||||
d:DesignWidth="800"
|
||||
mc:Ignorable="d"
|
||||
x:Class="Nebula.Launcher.Views.Pages.AccountInfoPage"
|
||||
xmlns="https://github.com/avaloniaui"
|
||||
xmlns:controls="clr-namespace:Nebula.Launcher.Views.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
<Grid ColumnDefinitions="*,1.5*" RowDefinitions="*">
|
||||
<StackPanel Grid.Column="0" Grid.Row="0">
|
||||
<Border
|
||||
CornerRadius="10"
|
||||
Margin="5"
|
||||
Padding="15">
|
||||
<StackPanel HorizontalAlignment="Center">
|
||||
<Image
|
||||
Height="100"
|
||||
Margin="0,0,0,20"
|
||||
Source="/Assets/account.png" />
|
||||
<Grid ColumnDefinitions="120, 100" RowDefinitions="Auto, Auto, Auto">
|
||||
<Label Grid.Column="0" Grid.Row="0">Login:</Label>
|
||||
<TextBox Grid.Column="1" Grid.Row="0" />
|
||||
<Label Grid.Column="0" Grid.Row="1">Password:</Label>
|
||||
<TextBox
|
||||
Grid.Column="1"
|
||||
Grid.Row="1"
|
||||
PasswordChar="#"
|
||||
Text="Sas" />
|
||||
<Label Grid.Column="0" Grid.Row="2">Auth server:</Label>
|
||||
<TextBox Grid.Column="1" Grid.Row="2" />
|
||||
</Grid>
|
||||
<StackPanel
|
||||
HorizontalAlignment="Center"
|
||||
Margin="5"
|
||||
Orientation="Horizontal">
|
||||
<Button>Save profile</Button>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Grid.Column="1" Grid.Row="0">
|
||||
<Border
|
||||
CornerRadius="10,10,0,0"
|
||||
Margin="5,5,5,0"
|
||||
Padding="5">
|
||||
<Label HorizontalAlignment="Center">Profiles:</Label>
|
||||
</Border>
|
||||
<ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
|
||||
<StackPanel>
|
||||
<controls:PlayerContainerControl />
|
||||
<controls:PlayerContainerControl />
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
19
Nebula.Launcher/Views/Pages/AccountInfoPage.axaml.cs
Normal file
19
Nebula.Launcher/Views/Pages/AccountInfoPage.axaml.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using Avalonia.Controls;
|
||||
using Nebula.Launcher.ViewModels;
|
||||
|
||||
namespace Nebula.Launcher.Views.Pages;
|
||||
|
||||
public interface ITab;
|
||||
public partial class AccountInfoPage : UserControl
|
||||
{
|
||||
public AccountInfoPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public AccountInfoPage(AccountInfoViewModel viewModel)
|
||||
: this()
|
||||
{
|
||||
DataContext = viewModel;
|
||||
}
|
||||
}
|
||||
41
Nebula.Launcher/Views/Pages/ServerListPage.axaml
Normal file
41
Nebula.Launcher/Views/Pages/ServerListPage.axaml
Normal file
@@ -0,0 +1,41 @@
|
||||
<UserControl
|
||||
d:DesignHeight="450"
|
||||
d:DesignWidth="800"
|
||||
mc:Ignorable="d"
|
||||
x:Class="Nebula.Launcher.Views.Pages.ServerListPage"
|
||||
xmlns="https://github.com/avaloniaui"
|
||||
xmlns:controls="clr-namespace:Nebula.Launcher.Views.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
<Grid ColumnDefinitions="*" RowDefinitions="*,40">
|
||||
<ScrollViewer Margin="0,0,0,10" Padding="0,0,8,0">
|
||||
<StackPanel>
|
||||
<controls:ServerContainerControl />
|
||||
<controls:ServerContainerControl />
|
||||
<controls:ServerContainerControl />
|
||||
<controls:ServerContainerControl />
|
||||
<controls:ServerContainerControl />
|
||||
<controls:ServerContainerControl />
|
||||
<controls:ServerContainerControl />
|
||||
<controls:ServerContainerControl />
|
||||
<controls:ServerContainerControl />
|
||||
<controls:ServerContainerControl />
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
<Border
|
||||
BorderThickness="2,0,0,0"
|
||||
CornerRadius="10"
|
||||
Grid.Row="1">
|
||||
<Grid ColumnDefinitions="*,40" RowDefinitions="*">
|
||||
<TextBox
|
||||
Margin="0"
|
||||
VerticalAlignment="Center"
|
||||
Watermark="Server name..." />
|
||||
<Button Grid.Column="1" Padding="10">
|
||||
<Image Source="/Assets/filter.png" />
|
||||
</Button>
|
||||
</Grid>
|
||||
</Border>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
11
Nebula.Launcher/Views/Pages/ServerListPage.axaml.cs
Normal file
11
Nebula.Launcher/Views/Pages/ServerListPage.axaml.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using Avalonia.Controls;
|
||||
|
||||
namespace Nebula.Launcher.Views.Pages;
|
||||
|
||||
public partial class ServerListPage : UserControl
|
||||
{
|
||||
public ServerListPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:controls="clr-namespace:Nebula.Launcher.Views.Controls"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="Nebula.Launcher.Views.Tabs.AccountInfoTab">
|
||||
<Grid ColumnDefinitions="*,1.5*" RowDefinitions="*">
|
||||
<StackPanel Grid.Column="0" Grid.Row="0">
|
||||
<Border
|
||||
Padding="15" Margin="5"
|
||||
CornerRadius="10">
|
||||
<StackPanel HorizontalAlignment="Center">
|
||||
<Image Source="/Assets/account.png" Height="100" Margin="0,0,0,20"/>
|
||||
<Grid ColumnDefinitions="120, 100" RowDefinitions="Auto, Auto, Auto">
|
||||
<TextBlock Grid.Row="0" Grid.Column="0">Login:</TextBlock>
|
||||
<TextBox Grid.Row="0" Grid.Column="1"></TextBox>
|
||||
<TextBlock Grid.Row="1" Grid.Column="0">Password:</TextBlock>
|
||||
<TextBox Grid.Row="1" Grid.Column="1" PasswordChar="#" Text="Sas"></TextBox>
|
||||
<TextBlock Grid.Row="2" Grid.Column="0">Auth server:</TextBlock>
|
||||
<TextBox Grid.Row="2" Grid.Column="1"></TextBox>
|
||||
</Grid>
|
||||
<StackPanel Orientation="Horizontal" Margin="5" HorizontalAlignment="Center">
|
||||
<Button>Save profile</Button>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Grid.Column="1" Grid.Row="0">
|
||||
<Border Padding="5" Margin="5,5,5,0"
|
||||
CornerRadius="10,10,0,0">
|
||||
<TextBlock HorizontalAlignment="Center">Profiles:</TextBlock>
|
||||
</Border>
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled">
|
||||
<StackPanel>
|
||||
<controls:PlayerContainerControl/>
|
||||
<controls:PlayerContainerControl/>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -1,13 +0,0 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
|
||||
namespace Nebula.Launcher.Views.Tabs;
|
||||
|
||||
public partial class AccountInfoTab : UserControl
|
||||
{
|
||||
public AccountInfoTab()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:controls="clr-namespace:Nebula.Launcher.Views.Controls"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="Nebula.Launcher.Views.Tabs.ServerListTab">
|
||||
<Grid ColumnDefinitions="*" RowDefinitions="*,40">
|
||||
<ScrollViewer>
|
||||
<StackPanel>
|
||||
<controls:ServerContainerControl/>
|
||||
<controls:ServerContainerControl/>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
<Border Grid.Row="1" CornerRadius="10" BorderThickness="2,0,0,0">
|
||||
<Grid ColumnDefinitions="*,40" RowDefinitions="*">
|
||||
<TextBlock VerticalAlignment="Center" Margin="10">Search...</TextBlock>
|
||||
<Button Grid.Column="1" Padding="10"><Image Source="/Assets/filter.png"/></Button>
|
||||
</Grid>
|
||||
</Border>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -1,11 +0,0 @@
|
||||
using Avalonia.Controls;
|
||||
|
||||
namespace Nebula.Launcher.Views.Tabs;
|
||||
|
||||
public partial class ServerListTab : UserControl
|
||||
{
|
||||
public ServerListTab()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user