Skip to content
This repository has been archived by the owner on Dec 19, 2022. It is now read-only.

Commit

Permalink
More tray stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
drasticactions committed Jan 2, 2022
1 parent ba943d3 commit 39d1157
Show file tree
Hide file tree
Showing 8 changed files with 227 additions and 16 deletions.
2 changes: 1 addition & 1 deletion DrasticMaui.Sample/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,6 @@ private void TrayIcon_MenuClicked(object? sender, DrasticTrayMenuClickedEventArg

/// <inheritdoc/>
protected override Window CreateWindow(IActivationState? activationState)
// => new DrasticMauiSampleWindow() { Page = new NavigationPage(new MainPage()) };
//=> new DrasticMauiSampleWindow() { Page = new NavigationPage(new MainPage()) };
=> new DrasticMauiSampleTrayWindow(this.icon) { Page = new TraySample() };
}
2 changes: 1 addition & 1 deletion DrasticMaui.sln
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.1.32023.32
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DrasticMaui.Sample", "DrasticMaui.Sample\DrasticMaui.Sample.csproj", "{BD39811E-11BA-47FA-9F6A-A322AAAE1057}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DrasticMaui.Sample", "DrasticMaui.Sample\DrasticMaui.Sample.csproj", "{BD39811E-11BA-47FA-9F6A-A322AAAE1057}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DrasticMaui", "DrasticMaui\DrasticMaui.csproj", "{ABBB7C06-7C93-4091-81FB-FAB580FBE76D}"
EndProject
Expand Down
32 changes: 30 additions & 2 deletions DrasticMaui/DrasticTrayWindow.MacCatalyst.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,13 @@
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CoreAnimation;
using CoreGraphics;
using DrasticMaui.Tools;
using Foundation;
using Microsoft.Maui.Handlers;
using ObjCRuntime;
using UIKit;

namespace DrasticMaui
{
Expand All @@ -20,13 +24,15 @@ public partial class DrasticTrayWindow
{
private UIKit.UIWindow? uiWindow;
private NSObject? nsWindow;
private bool isActivated;
private DrasticTrayUIViewController? drasticViewController;

/// <summary>
/// Gets a value indicating whether the tray window should be visible.
/// </summary>
public bool IsVisible => true;

private void SetupWindow()
private async void SetupWindow()
{
var handler = this.Handler as Microsoft.Maui.Handlers.WindowHandler;
if (handler?.NativeView is not UIKit.UIWindow uiWindow)
Expand All @@ -35,7 +41,27 @@ private void SetupWindow()
}

this.uiWindow = uiWindow;
this.nsWindow = uiWindow.GetNSWindowFromUIWindow();

this.nsWindow = await this.uiWindow.GetNSWindowFromUIWindow();



await this.uiWindow.ToggleTitleBarButtons(true);

if (this.uiWindow.RootViewController is null)
{
return;
}

this.uiWindow.RootViewController = this.drasticViewController = new DrasticTrayUIViewController(this.uiWindow, this.uiWindow.RootViewController, this.icon, this.options);

}

protected override void OnHandlerChanged()
{
base.OnHandlerChanged();
this.SetupWindow();
this.SetupTrayIcon();
}

private void TestUIWindowToTray()
Expand Down Expand Up @@ -68,10 +94,12 @@ private void TestUIWindowToTray()

private void ShowWindow()
{
this.drasticViewController?.ToggleVisibility();
}

private void HideWindow()
{
this.drasticViewController?.ToggleVisibility();
}
}
}
8 changes: 8 additions & 0 deletions DrasticMaui/DrasticTrayWindow.Windows.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@ public partial class DrasticTrayWindow
/// </summary>
public bool IsVisible => this.appWindow is not null ? this.appWindow.IsVisible : true;

///// <inheritdoc/>
protected override void OnCreated()
{
base.OnCreated();
this.SetupWindow();
this.SetupTrayIcon();
}

private void SetupWindow()
{
var handler = this.Handler as Microsoft.Maui.Handlers.WindowHandler;
Expand Down
8 changes: 0 additions & 8 deletions DrasticMaui/DrasticTrayWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,6 @@ public DrasticTrayWindow(DrasticTrayIcon icon, DrasticTrayWindowOptions? options
this.options = options ?? new DrasticTrayWindowOptions();
}

/// <inheritdoc/>
protected override void OnCreated()
{
base.OnCreated();
this.SetupWindow();
this.SetupTrayIcon();
}

private void SetupTrayIcon()
{
if (this.icon is null)
Expand Down
63 changes: 59 additions & 4 deletions DrasticMaui/Tools/PlatformExtensions.iOS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ public static CATransform3D TransformToAncestor(this CALayer fromLayer, CALayer
/// </summary>
/// <param name="window">UIWindow.</param>
/// <returns>NSWindow as NSObject.</returns>
public static NSObject? GetNSWindowFromUIWindow(this UIWindow window)
public static async Task<NSObject?> GetNSWindowFromUIWindow(this UIWindow window)
{
if (window is null)
{
Expand All @@ -299,19 +299,71 @@ public static CATransform3D TransformToAncestor(this CALayer fromLayer, CALayer
return null;
}

return await GetNSWindow(window, applicationDelegate);
}

public static async Task<NSObject?> GetNSWindow(UIWindow window, NSObject applicationDelegate)
{
var nsWindowHandle = IntPtr_objc_msgSend_IntPtr(applicationDelegate.Handle, Selector.GetHandle("hostWindowForUIWindow:"), window.Handle);
var nsWindow = Runtime.GetNSObject(nsWindowHandle);
var nsWindow = Runtime.GetNSObject<NSObject>(nsWindowHandle);
if (nsWindow is null)
{
return null;
await Task.Delay(500);
return await GetNSWindow(window, applicationDelegate);
}

return nsWindow;
}

public static async Task SetFrameForUIWindow(this UIWindow window, CGRect rect)
{
var nsWindow = await window.GetNSWindowFromUIWindow();
if (nsWindow is null)
{
return;
}

var newRect = NSValue.FromCGRect(rect);

void_objc_msgSend_IntPtr_bool(nsWindow.Handle, Selector.GetHandle("setFrame:display:"), newRect.Handle, false);
}

public static async Task ToggleTitleBarButtons(this UIWindow window, bool hideButtons)
{
var nsWindow = await window.GetNSWindowFromUIWindow();
if (nsWindow is null)
{
return;
}

var closeButton = Runtime.GetNSObject(IntPtr_objc_msgSend_nfloat(nsWindow.Handle, Selector.GetHandle("standardWindowButton:"), 0));

if (closeButton is null)
{
return;
}

var miniaturizeButton = Runtime.GetNSObject(IntPtr_objc_msgSend_nfloat(nsWindow.Handle, Selector.GetHandle("standardWindowButton:"), 1));
if (miniaturizeButton is null)
{
return;
}

var zoomButton = Runtime.GetNSObject(IntPtr_objc_msgSend_nfloat(nsWindow.Handle, Selector.GetHandle("standardWindowButton:"), 2));

if (zoomButton is null)
{
return;
}

void_objc_msgSend_bool(closeButton.Handle, Selector.GetHandle("isHidden"), hideButtons);
void_objc_msgSend_bool(miniaturizeButton.Handle, Selector.GetHandle("isHidden"), hideButtons);
void_objc_msgSend_bool(zoomButton.Handle, Selector.GetHandle("isHidden"), hideButtons);
}

public static void ToggleFullScreen(this UIWindow window, bool fullScreen)
{
var nsWindow = window.GetNSWindowFromUIWindow();
var nsWindow = window.GetNSWindowFromUIWindow().Result;
if (nsWindow is null)
{
return;
Expand Down Expand Up @@ -361,6 +413,9 @@ public static void NSApplicationActivateIgnoringOtherApps(bool ignoreSetting = t

[DllImport("/usr/lib/libobjc.dylib", EntryPoint = "objc_msgSend")]
internal static extern void void_objc_msgSend_bool(IntPtr receiver, IntPtr selector, bool arg1);

[DllImport("/usr/lib/libobjc.dylib", EntryPoint = "objc_msgSend")]
internal static extern void void_objc_msgSend_ulong(IntPtr receiver, IntPtr selector, ulong arg1);
#endif
}
}
22 changes: 22 additions & 0 deletions DrasticMaui/Tray/DrasticTrayIcon.MacCatalyst.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,28 @@ public partial class DrasticTrayIcon : NSObject
private NSObject? statusBarItem;
private NSObject? statusBarButton;

public CGRect GetFrame()
{
if (this.statusBarButton is null)
{
return new CGRect(0, 0, 1, 1);
}

var buttonValue = Runtime.GetNSObject<NSValue>(PlatformExtensions.IntPtr_objc_msgSend(this.statusBarButton.Handle, Selector.GetHandle("frame")));
if (buttonValue is null)
{
return new CGRect(0, 0, 1, 1);
}

//var cgRectWindowFrame = Runtime.GetNSObject(PlatformExtensions.IntPtr_objc_msgSend(buttonWindow.Handle, Selector.GetHandle("frame")));
//if (cgRectWindowFrame is null)
//{
// return new CGRect(0, 0, 1, 1);
//}

return new CGRect(0, 0, 1, 1);
}

private void SetupStatusBarButton()
{
this.statusBarObj = Runtime.GetNSObject(Class.GetHandle("NSStatusBar"));
Expand Down
106 changes: 106 additions & 0 deletions DrasticMaui/Tray/DrasticTrayUIViewController.MacCatalyst.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
using System;
using CoreGraphics;
using DrasticMaui.Options;
using DrasticMaui.Tools;
using Foundation;
using UIKit;

namespace DrasticMaui
{
public class DrasticTrayUIViewController : UIViewController
{
private UIViewController contentController;
private UIImage? image;
private UIWindow window;
private DrasticTrayWindowOptions options;
private DrasticTrayIcon trayIcon;

public DrasticTrayUIViewController(
UIWindow window,
UIViewController contentController,
DrasticTrayIcon trayIcon,
DrasticTrayWindowOptions options)
{
this.trayIcon = trayIcon;
this.options = options;
this.window = window;
this.contentController = contentController;
this.image = UIImage.GetSystemImage("cursorarrow.click.2");
this.SetupWindow();
}

public async void ToggleVisibility()
{
if (this.contentController?.View is null)
{
return;
}

if (this.View is null)
{
return;
}

//var frame = this.trayIcon.GetFrame();
//await this.window.SetFrameForUIWindow(new CGRect(500, 500, 1000, 1000));
var viewController = this.contentController;

if (viewController.PresentingViewController is not null)
{
viewController.DismissViewController(true, null);
}
else
{
viewController.ModalPresentationStyle = UIModalPresentationStyle.Popover;
viewController.PopoverPresentationController.SourceView = this.View;
viewController.PopoverPresentationController.SourceRect = new CGRect(0, 0, 1, 1);
viewController.PopoverPresentationController.PermittedArrowDirections = UIPopoverArrowDirection.Up;
this.PresentViewController(viewController, true, null);
}
}

public override void ViewDidAppear(bool animated)
{
base.ViewDidAppear(animated);
this.PrepareForAppearance();
this.ForceContentViewLayout();
}

private async void PrepareForAppearance()
{
if (this.window is not null)
{
await this.window.ToggleTitleBarButtons(true);
}
}

private void ForceContentViewLayout()
{
if (this.contentController.View is not null)
{
this.View?.AddSubview(this.contentController.View);
this.contentController.View.Frame = new CoreGraphics.CGRect(0, 0, this.options.WindowWidth, this.options.WindowHeight);
this.View?.LayoutIfNeeded();
this.contentController.View.RemoveFromSuperview();
}
}

private void SetupWindow()
{
this.window.RootViewController = this;
if (this.window.WindowScene?.Titlebar is null)
{
return;
}

if (this.window.WindowScene?.SizeRestrictions is null)
{
return;
}

this.window.WindowScene.Titlebar.TitleVisibility = UITitlebarTitleVisibility.Hidden;
this.window.WindowScene.SizeRestrictions.MinimumSize = new CoreGraphics.CGSize(1, 1);
this.window.WindowScene.SizeRestrictions.MaximumSize = new CoreGraphics.CGSize(1, 1);
}
}
}

0 comments on commit 39d1157

Please sign in to comment.