Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Dev/2.0] close context menu on window events #845

Merged
merged 3 commits into from
Jun 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

namespace DevToys.Blazor.Components;

// TODO: Close the context menu when the window lose focus or get resized.
public partial class ContextMenu : StyledComponentBase
{
private bool _isOpen;
Expand Down
17 changes: 17 additions & 0 deletions src/app/dev/DevToys.Blazor/Core/Services/ContextMenuService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,18 @@
public sealed class ContextMenuService
{
private readonly object _lock = new();
private readonly IWindowService _windowService;

public ContextMenuService(IWindowService windowService)
{
Guard.IsNotNull(windowService);
_windowService = windowService;

_windowService.WindowLostFocus += WindowService_MajorWindowChange;
_windowService.WindowClosing += WindowService_MajorWindowChange;
_windowService.WindowLocationChanged += WindowService_MajorWindowChange;
_windowService.WindowSizeChanged += WindowService_MajorWindowChange;
}

internal bool IsContextMenuOpened { get; private set; }

Expand Down Expand Up @@ -39,4 +51,9 @@ internal void OnCloseContextMenuRequested()
{
CloseContextMenuRequested?.Invoke(this, EventArgs.Empty);
}

private void WindowService_MajorWindowChange(object? sender, EventArgs e)
{
OnCloseContextMenuRequested();
}
}
12 changes: 12 additions & 0 deletions src/app/dev/DevToys.Blazor/Core/Services/IWindowService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace DevToys.Blazor.Core.Services;

public interface IWindowService
{
event EventHandler<EventArgs>? WindowLostFocus;

event EventHandler<EventArgs>? WindowLocationChanged;

event EventHandler<EventArgs>? WindowSizeChanged;

event EventHandler<EventArgs>? WindowClosing;
}
9 changes: 9 additions & 0 deletions src/app/dev/platforms/desktop/DevToys.MacOS/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,13 @@ public App()

MainPage = new MainPage();
}

protected override Window CreateWindow(IActivationState? activationState)
{
Window window = base.CreateWindow(activationState);
window.Width = 800;
window.Height = 600;

return window;
}
}
40 changes: 40 additions & 0 deletions src/app/dev/platforms/desktop/DevToys.MacOS/Core/WindowService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using DevToys.Blazor.Core.Services;
using Foundation;

namespace DevToys.MacOS.Core;

internal sealed class WindowService : IWindowService
{
public event EventHandler<EventArgs>? WindowLostFocus;
public event EventHandler<EventArgs>? WindowLocationChanged;
public event EventHandler<EventArgs>? WindowSizeChanged;
public event EventHandler<EventArgs>? WindowClosing;

public WindowService()
{
NSNotificationCenter.DefaultCenter.AddObserver(new NSString("NSWindowDidResignMainNotification"), OnWindowLostFocus);
NSNotificationCenter.DefaultCenter.AddObserver(new NSString("NSWindowWillMoveNotification"), OnWindowLocationChanged);
NSNotificationCenter.DefaultCenter.AddObserver(new NSString("NSWindowWillStartLiveResizeNotification"), OnWindowSizeChanged);
NSNotificationCenter.DefaultCenter.AddObserver(new NSString("NSWindowWillCloseNotification"), OnWindowClosing);
}

public void OnWindowLostFocus(NSNotification notification)
{
WindowLostFocus?.Invoke(this, EventArgs.Empty);
}

public void OnWindowLocationChanged(NSNotification notification)
{
WindowLocationChanged?.Invoke(this, EventArgs.Empty);
}

public void OnWindowSizeChanged(NSNotification notification)
{
WindowSizeChanged?.Invoke(this, EventArgs.Empty);
}

public void OnWindowClosing(NSNotification notification)
{
WindowClosing?.Invoke(this, EventArgs.Empty);
}
}
8 changes: 4 additions & 4 deletions src/app/dev/platforms/desktop/DevToys.MacOS/MauiProgram.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
using DevToys.Api;
using DevToys.Blazor.Core.Languages;
using DevToys.Blazor.Services;
using DevToys.Blazor.Core.Services;
using DevToys.Business.ViewModels;
using DevToys.Core.Logging;
using DevToys.Core.Mef;
using DevToys.MacOS.Core;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Logging;
using Uno.Extensions;
using PredefinedSettings = DevToys.Core.Settings.PredefinedSettings;
Expand Down Expand Up @@ -97,8 +96,9 @@ private ServiceProvider InitializeServices(IServiceCollection serviceCollection)
});

serviceCollection.AddSingleton(provider => MefComposer!.Provider);
serviceCollection.TryAddScoped<PopoverService, PopoverService>();
serviceCollection.TryAddScoped<ContextMenuService, ContextMenuService>();
serviceCollection.AddSingleton<IWindowService, WindowService>();
serviceCollection.AddScoped<PopoverService, PopoverService>();
serviceCollection.AddScoped<ContextMenuService, ContextMenuService>();

ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using System.Windows;
using DevToys.Blazor.Core.Services;

namespace DevToys.Windows.Core;

internal sealed class WindowService : IWindowService
{
private Window? _window;

public event EventHandler<EventArgs>? WindowLostFocus;
public event EventHandler<EventArgs>? WindowLocationChanged;
public event EventHandler<EventArgs>? WindowSizeChanged;
public event EventHandler<EventArgs>? WindowClosing;

internal void SetWindow(Window window)
{
Guard.IsNull(_window);
Guard.IsNotNull(window);
_window = window;

_window.LostFocus += Window_LostFocus;
_window.LocationChanged += Window_LocationChanged;
_window.SizeChanged += Window_SizeChanged;
_window.Closing += Window_Closing;
}

private void Window_LostFocus(object sender, RoutedEventArgs e)
{
WindowLostFocus?.Invoke(this, EventArgs.Empty);
}

private void Window_LocationChanged(object? sender, EventArgs e)
{
WindowLocationChanged?.Invoke(this, EventArgs.Empty);
}

private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
{
WindowSizeChanged?.Invoke(this, EventArgs.Empty);
}

private void Window_Closing(object? sender, CancelEventArgs e)
{
WindowClosing?.Invoke(this, EventArgs.Empty);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
xmlns:controls="clr-namespace:DevToys.Windows.Controls"
xmlns:blazor="clr-namespace:Microsoft.AspNetCore.Components.WebView.Wpf;assembly=Microsoft.AspNetCore.Components.WebView.Wpf"
mc:Ignorable="d"
Loaded="MainWindow_Loaded"
Title="MainWindow"
Height="450"
Width="800"
Expand Down
20 changes: 14 additions & 6 deletions src/app/dev/platforms/desktop/DevToys.Windows/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using DevToys.Api;
using System;
using DevToys.Api;
using DevToys.Blazor.Core.Languages;
using DevToys.Blazor.Core.Services;
using DevToys.Business.ViewModels;
Expand All @@ -9,7 +10,6 @@
using DevToys.Windows.Core;
using Microsoft.AspNetCore.Components.WebView;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Logging;
using PredefinedSettings = DevToys.Core.Settings.PredefinedSettings;

Expand All @@ -23,6 +23,7 @@ public partial class MainWindow : MicaWindowWithOverlay
private static MainWindow? mainWindowInstance;

private readonly MefComposer _mefComposer;
private readonly ServiceProvider _serviceProvider;
private readonly DateTime _uiLoadingTime;
private ILogger? _logger;

Expand All @@ -33,7 +34,7 @@ public MainWindow()
DateTime startTime = DateTime.Now;

// Initialize services and logging.
ServiceProvider serviceProvider = InitializeServices();
_serviceProvider = InitializeServices();

// Listen for unhandled exceptions.
AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
Expand All @@ -58,7 +59,7 @@ LanguageDefinition languageDefinition
LanguageManager.Instance.SetCurrentCulture(languageDefinition);

// Load the UI.
Resources.Add("services", serviceProvider);
Resources.Add("services", _serviceProvider);
InitializeComponent();

_themeListener = _mefComposer.Provider.Import<IThemeListener>();
Expand All @@ -68,6 +69,12 @@ LanguageDefinition languageDefinition
blazorWebView.BlazorWebViewInitialized += BlazorWebView_BlazorWebViewInitialized;
}

private void MainWindow_Loaded(object sender, System.Windows.RoutedEventArgs e)
{
var windowService = (WindowService)_serviceProvider.GetService<IWindowService>()!;
windowService.SetWindow(this);
}

private void BlazorWebView_BlazorWebViewInitializing(object? sender, BlazorWebViewInitializingEventArgs e)
{
// Set the web view transparent.
Expand Down Expand Up @@ -113,8 +120,9 @@ private ServiceProvider InitializeServices()
});

serviceCollection.AddSingleton(provider => _mefComposer.Provider);
serviceCollection.TryAddScoped<PopoverService, PopoverService>();
serviceCollection.TryAddScoped<ContextMenuService, ContextMenuService>();
serviceCollection.AddSingleton<IWindowService, WindowService>();
serviceCollection.AddScoped<PopoverService, PopoverService>();
serviceCollection.AddScoped<ContextMenuService, ContextMenuService>();

ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();

Expand Down