From 516801840c2da31db8b5125115290e8f3092a03b Mon Sep 17 00:00:00 2001 From: Cinka Date: Thu, 26 Dec 2024 18:54:37 +0300 Subject: [PATCH] - add: popup message --- .idea/.idea.Nebula/.idea/avalonia.xml | 2 + .../ServiceCollectionExtensions.cs | 4 +- .../ViewHelper/ViewRegisterAttribute.cs | 5 +- .../ViewModels/AccountInfoViewModel.cs | 4 +- .../ViewModels/InfoPopupViewModel.cs | 22 +++ Nebula.Launcher/ViewModels/MainViewModel.cs | 33 +++- .../ViewModels/MessagePopupViewModel.cs | 68 ++++++++ .../ViewModels/PopupViewModelBase.cs | 16 ++ Nebula.Launcher/ViewModels/ViewModelBase.cs | 13 ++ Nebula.Launcher/Views/MainView.axaml | 151 ++++++++++-------- .../Views/Popup/InfoPopupView.axaml | 21 +++ .../Views/Popup/InfoPopupView.axaml.cs | 19 +++ .../Views/Popup/MessagePopupView.axaml | 53 ++++++ .../Views/Popup/MessagePopupView.axaml.cs | 26 +++ 14 files changed, 367 insertions(+), 70 deletions(-) create mode 100644 Nebula.Launcher/ViewModels/InfoPopupViewModel.cs create mode 100644 Nebula.Launcher/ViewModels/MessagePopupViewModel.cs create mode 100644 Nebula.Launcher/ViewModels/PopupViewModelBase.cs create mode 100644 Nebula.Launcher/Views/Popup/InfoPopupView.axaml create mode 100644 Nebula.Launcher/Views/Popup/InfoPopupView.axaml.cs create mode 100644 Nebula.Launcher/Views/Popup/MessagePopupView.axaml create mode 100644 Nebula.Launcher/Views/Popup/MessagePopupView.axaml.cs 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"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + VerticalAlignment="Stretch"> + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + +