diff --git a/.idea/.idea.Nebula/.idea/avalonia.xml b/.idea/.idea.Nebula/.idea/avalonia.xml
index b1ca469..f25c2ce 100644
--- a/.idea/.idea.Nebula/.idea/avalonia.xml
+++ b/.idea/.idea.Nebula/.idea/avalonia.xml
@@ -15,6 +15,8 @@
+
+
diff --git a/Nebula.Launcher/ServiceCollectionExtensions.cs b/Nebula.Launcher/ServiceCollectionExtensions.cs
index 723723e..d92a01b 100644
--- a/Nebula.Launcher/ServiceCollectionExtensions.cs
+++ b/Nebula.Launcher/ServiceCollectionExtensions.cs
@@ -85,9 +85,11 @@ public static class ServiceCollectionExtensions
public sealed class ServiceRegisterAttribute : Attribute
{
public Type? Inference { get; }
+ public bool IsSingleton { get; }
- public ServiceRegisterAttribute(Type? inference = null)
+ public ServiceRegisterAttribute(Type? inference = null, bool isSingleton = true)
{
+ IsSingleton = isSingleton;
Inference = inference;
}
}
\ No newline at end of file
diff --git a/Nebula.Launcher/ViewHelper/ViewRegisterAttribute.cs b/Nebula.Launcher/ViewHelper/ViewRegisterAttribute.cs
index 7ca0bd0..b15cb4c 100644
--- a/Nebula.Launcher/ViewHelper/ViewRegisterAttribute.cs
+++ b/Nebula.Launcher/ViewHelper/ViewRegisterAttribute.cs
@@ -2,12 +2,15 @@ using System;
namespace Nebula.Launcher.ViewHelper;
+[AttributeUsage(AttributeTargets.Class)]
public class ViewRegisterAttribute : Attribute
{
public Type Type { get; }
+ public bool IsSingleton { get; }
- public ViewRegisterAttribute(Type type)
+ public ViewRegisterAttribute(Type type, bool isSingleton = true)
{
Type = type;
+ IsSingleton = isSingleton;
}
}
\ No newline at end of file
diff --git a/Nebula.Launcher/ViewModels/AccountInfoViewModel.cs b/Nebula.Launcher/ViewModels/AccountInfoViewModel.cs
index 7ead05f..fc95a05 100644
--- a/Nebula.Launcher/ViewModels/AccountInfoViewModel.cs
+++ b/Nebula.Launcher/ViewModels/AccountInfoViewModel.cs
@@ -85,12 +85,12 @@ public partial class AccountInfoViewModel : ViewModelBase
}
}
-internal class Ref
+public class Ref
{
public T Value = default!;
}
-internal class DelegateCommand : ICommand
+public class DelegateCommand : ICommand
{
private readonly Action _func;
public readonly Ref TRef = new();
diff --git a/Nebula.Launcher/ViewModels/InfoPopupViewModel.cs b/Nebula.Launcher/ViewModels/InfoPopupViewModel.cs
new file mode 100644
index 0000000..c7e8bf0
--- /dev/null
+++ b/Nebula.Launcher/ViewModels/InfoPopupViewModel.cs
@@ -0,0 +1,22 @@
+using System;
+using CommunityToolkit.Mvvm.ComponentModel;
+using Nebula.Launcher.ViewHelper;
+using Nebula.Launcher.Views.Popup;
+
+namespace Nebula.Launcher.ViewModels;
+
+[ViewRegister(typeof(InfoPopupView), false)]
+public partial class InfoPopupViewModel : PopupViewModelBase
+{
+ public InfoPopupViewModel()
+ {
+ }
+
+ public InfoPopupViewModel(IServiceProvider serviceProvider) : base(serviceProvider)
+ {
+ }
+ public override string Title => "Info";
+
+ [ObservableProperty]
+ private string _infoText = "Test";
+}
\ No newline at end of file
diff --git a/Nebula.Launcher/ViewModels/MainViewModel.cs b/Nebula.Launcher/ViewModels/MainViewModel.cs
index 93b8407..8861cae 100644
--- a/Nebula.Launcher/ViewModels/MainViewModel.cs
+++ b/Nebula.Launcher/ViewModels/MainViewModel.cs
@@ -21,19 +21,39 @@ public partial class MainViewModel : ViewModelBase
{
TryGetViewModel(typeof(AccountInfoViewModel), out var model);
_currentPage = model!;
+ TryGetViewModel(typeof(MessagePopupViewModel), out var viewModelBase);
+ _messagePopupViewModel = (MessagePopupViewModel)viewModelBase!;
+
Items = new ObservableCollection(_templates);
SelectedListItem = Items.First(vm => vm.ModelType == typeof(AccountInfoViewModel));
}
- public MainViewModel(AccountInfoViewModel accountInfoViewModel, IServiceProvider serviceProvider): base(serviceProvider)
+ public MainViewModel(AccountInfoViewModel accountInfoViewModel, MessagePopupViewModel messagePopupViewModel,
+ IServiceProvider serviceProvider): base(serviceProvider)
{
_currentPage = accountInfoViewModel;
+ _messagePopupViewModel = messagePopupViewModel;
Items = new ObservableCollection(_templates);
+
+ _messagePopupViewModel.OnOpenRequired += () => OnOpenRequired();
+ _messagePopupViewModel.OnCloseRequired += () => OnCloseRequired();
SelectedListItem = Items.First(vm => vm.ModelType == typeof(AccountInfoViewModel));
}
+ private void OnCloseRequired()
+ {
+ IsEnabled = true;
+ Popup = false;
+ }
+
+ private void OnOpenRequired()
+ {
+ IsEnabled = false;
+ Popup = true;
+ }
+
private readonly List _templates =
[
new ListItemTemplate(typeof(AccountInfoViewModel), "Account", "Account"),
@@ -46,6 +66,11 @@ public partial class MainViewModel : ViewModelBase
[ObservableProperty]
private ViewModelBase _currentPage;
+ [ObservableProperty] private bool _isEnabled = true;
+ [ObservableProperty] private bool _popup;
+
+ private readonly MessagePopupViewModel _messagePopupViewModel;
+
[ObservableProperty]
private ListItemTemplate? _selectedListItem;
@@ -59,6 +84,12 @@ public partial class MainViewModel : ViewModelBase
}
CurrentPage = vmb;
+
+ var model = GetViewModel();
+ model.InfoText = "Переключили прикол!";
+
+ _messagePopupViewModel.PopupMessage(model);
+
}
public ObservableCollection Items { get; }
diff --git a/Nebula.Launcher/ViewModels/MessagePopupViewModel.cs b/Nebula.Launcher/ViewModels/MessagePopupViewModel.cs
new file mode 100644
index 0000000..80657b8
--- /dev/null
+++ b/Nebula.Launcher/ViewModels/MessagePopupViewModel.cs
@@ -0,0 +1,68 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows.Input;
+using Avalonia.Logging;
+using CommunityToolkit.Mvvm.ComponentModel;
+using CommunityToolkit.Mvvm.Input;
+using Nebula.Launcher.ViewHelper;
+using Nebula.Launcher.Views.Popup;
+
+namespace Nebula.Launcher.ViewModels;
+
+[ViewRegister(typeof(MessagePopupView))]
+public partial class MessagePopupViewModel : ViewModelBase
+{
+ public MessagePopupViewModel() : base()
+ {
+ }
+
+ public MessagePopupViewModel(IServiceProvider serviceProvider) : base(serviceProvider)
+ {
+ }
+
+ public Action? OnCloseRequired;
+ public Action? OnOpenRequired;
+
+ public Queue ViewQueue = new();
+
+ [ObservableProperty]
+ private PopupViewModelBase? _currentPopup;
+
+ [ObservableProperty]
+ private string _currentTitle = "Default";
+
+ public void PopupMessage(PopupViewModelBase viewModelBase)
+ {
+ Console.WriteLine(viewModelBase.Title);
+ if (CurrentPopup == null)
+ {
+ CurrentPopup = viewModelBase;
+ CurrentTitle = viewModelBase.Title;
+ OnOpenRequired?.Invoke();
+ }
+ else
+ {
+ ViewQueue.Enqueue(viewModelBase);
+ }
+ }
+
+ [RelayCommand]
+ private void TriggerClose()
+ {
+ ClosePopup();
+ }
+
+ [RelayCommand]
+ private void ClosePopup()
+ {
+ Console.WriteLine("Gadeem");
+ if (!ViewQueue.TryDequeue(out var viewModelBase))
+ OnCloseRequired?.Invoke();
+ else
+ CurrentTitle = viewModelBase.Title;
+
+ CurrentPopup = viewModelBase;
+
+ }
+}
\ No newline at end of file
diff --git a/Nebula.Launcher/ViewModels/PopupViewModelBase.cs b/Nebula.Launcher/ViewModels/PopupViewModelBase.cs
new file mode 100644
index 0000000..32239f6
--- /dev/null
+++ b/Nebula.Launcher/ViewModels/PopupViewModelBase.cs
@@ -0,0 +1,16 @@
+using System;
+
+namespace Nebula.Launcher.ViewModels;
+
+public abstract class PopupViewModelBase : ViewModelBase
+{
+ public PopupViewModelBase()
+ {
+ }
+
+ public PopupViewModelBase(IServiceProvider serviceProvider) : base(serviceProvider)
+ {
+ }
+
+ public abstract string Title { get; }
+}
\ No newline at end of file
diff --git a/Nebula.Launcher/ViewModels/ViewModelBase.cs b/Nebula.Launcher/ViewModels/ViewModelBase.cs
index 7a4b88a..90ea18d 100644
--- a/Nebula.Launcher/ViewModels/ViewModelBase.cs
+++ b/Nebula.Launcher/ViewModels/ViewModelBase.cs
@@ -30,6 +30,19 @@ public abstract class ViewModelBase : ObservableObject
viewModelBase = vmb;
return true;
}
+
+ public bool TryGetViewModel([NotNullWhen(true)] out T? viewModelBase) where T: ViewModelBase
+ {
+ var success = TryGetViewModel(typeof(T), out var vmb);
+ viewModelBase = (T?)vmb;
+ return success;
+ }
+
+ public T GetViewModel() where T: ViewModelBase
+ {
+ TryGetViewModel(out var viewModelBase);
+ return viewModelBase!;
+ }
public void AssertDesignMode()
{
diff --git a/Nebula.Launcher/Views/MainView.axaml b/Nebula.Launcher/Views/MainView.axaml
index 24481ef..4f038d5 100644
--- a/Nebula.Launcher/Views/MainView.axaml
+++ b/Nebula.Launcher/Views/MainView.axaml
@@ -9,75 +9,96 @@
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:popup="clr-namespace:Nebula.Launcher.Views.Popup"
xmlns:viewModels="clr-namespace:Nebula.Launcher.ViewModels"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Nebula.Launcher/Views/Popup/InfoPopupView.axaml b/Nebula.Launcher/Views/Popup/InfoPopupView.axaml
new file mode 100644
index 0000000..a54d4a5
--- /dev/null
+++ b/Nebula.Launcher/Views/Popup/InfoPopupView.axaml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
diff --git a/Nebula.Launcher/Views/Popup/InfoPopupView.axaml.cs b/Nebula.Launcher/Views/Popup/InfoPopupView.axaml.cs
new file mode 100644
index 0000000..581969c
--- /dev/null
+++ b/Nebula.Launcher/Views/Popup/InfoPopupView.axaml.cs
@@ -0,0 +1,19 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+using Nebula.Launcher.ViewModels;
+
+namespace Nebula.Launcher.Views.Popup;
+
+public partial class InfoPopupView : UserControl
+{
+ public InfoPopupView()
+ {
+ InitializeComponent();
+ }
+
+ public InfoPopupView(InfoPopupViewModel viewModel) : this()
+ {
+ DataContext = viewModel;
+ }
+}
\ No newline at end of file
diff --git a/Nebula.Launcher/Views/Popup/MessagePopupView.axaml b/Nebula.Launcher/Views/Popup/MessagePopupView.axaml
new file mode 100644
index 0000000..c001fbb
--- /dev/null
+++ b/Nebula.Launcher/Views/Popup/MessagePopupView.axaml
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Nebula.Launcher/Views/Popup/MessagePopupView.axaml.cs b/Nebula.Launcher/Views/Popup/MessagePopupView.axaml.cs
new file mode 100644
index 0000000..51f8199
--- /dev/null
+++ b/Nebula.Launcher/Views/Popup/MessagePopupView.axaml.cs
@@ -0,0 +1,26 @@
+using System;
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+using Nebula.Launcher.ViewModels;
+
+namespace Nebula.Launcher.Views.Popup;
+
+public partial class MessagePopupView : UserControl
+{
+ // This constructor is used when the view is created by the XAML Previewer
+ public MessagePopupView()
+ {
+ InitializeComponent();
+ }
+
+ // This constructor is used when the view is created via dependency injection
+ public MessagePopupView(MessagePopupViewModel viewModel)
+ : this()
+ {
+ DataContext = viewModel;
+ Console.WriteLine("NO SOSAL");
+ CloseButton.KeyDown += (_,_) => Console.WriteLine("GGG11");
+ CloseButton.Click += (_,_) => Console.WriteLine("GGG");
+ }
+}
\ No newline at end of file