- tweak: Dependency injection think

This commit is contained in:
2024-12-21 13:11:30 +03:00
parent 9a1bd44a6e
commit 42fde38db6
27 changed files with 541 additions and 242 deletions

1
.idea/.idea.Nebula/.idea/.name generated Normal file
View File

@@ -0,0 +1 @@
Nebula

View File

@@ -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" />

View File

@@ -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>

View File

@@ -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();

View 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);
});
}

View File

@@ -0,0 +1,4 @@
using System;
namespace Nebula.Launcher.Models;
public record ListItemTemplate(Type ModelType, string IconKey, string Label);

View File

@@ -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>

View File

@@ -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();
}

View 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>();
}
}

View File

@@ -0,0 +1,8 @@
using Nebula.Launcher.Views.Pages;
namespace Nebula.Launcher.ViewModels;
public class AccountInfoViewModel : ViewModelBase, ITab
{
}

View 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;
}
}

View File

@@ -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";
}
}

View File

@@ -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
{
}

View File

@@ -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>

View File

@@ -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>

View 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>

View 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;
}
}

View File

@@ -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" />

View File

@@ -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;
}
}

View 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>

View 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;
}
}

View 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>

View File

@@ -0,0 +1,11 @@
using Avalonia.Controls;
namespace Nebula.Launcher.Views.Pages;
public partial class ServerListPage : UserControl
{
public ServerListPage()
{
InitializeComponent();
}
}

View File

@@ -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>

View File

@@ -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();
}
}

View File

@@ -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>

View File

@@ -1,11 +0,0 @@
using Avalonia.Controls;
namespace Nebula.Launcher.Views.Tabs;
public partial class ServerListTab : UserControl
{
public ServerListTab()
{
InitializeComponent();
}
}