Browse Source

Implement MacOSProperties.IsTemplateIcon attached property on TrayIcon (#14348)

* Implement MacOS.IsTemplateIcon attached property on TrayIcon

* Use MacOS.IsTemplateIcon in the ControlCatalog

* Rename MacOS to MacOSProperties

* Extract IsTemplateIcon to ITrayIconWithIsTemplateImpl
pull/14470/head
Max Katz 3 years ago
committed by GitHub
parent
commit
628a62e250
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 7
      native/Avalonia.Native/src/OSX/trayicon.h
  2. 22
      native/Avalonia.Native/src/OSX/trayicon.mm
  3. 2
      samples/ControlCatalog/App.xaml
  4. 9
      src/Avalonia.Controls/Platform/ITrayIconImpl.cs
  5. 35
      src/Avalonia.Controls/Platform/MacOSProperties.cs
  6. 2
      src/Avalonia.Controls/TrayIcon.cs
  7. 7
      src/Avalonia.Native/TrayIconImpl.cs
  8. 1
      src/Avalonia.Native/avn.idl
  9. 2
      src/Windows/Avalonia.Win32/TrayIconImpl.cs

7
native/Avalonia.Native/src/OSX/trayicon.h

@ -15,7 +15,8 @@ class AvnTrayIcon : public ComSingleObject<IAvnTrayIcon, &IID_IAvnTrayIcon>
{
private:
NSStatusItem* _native;
bool _isTemplateIcon;
public:
FORWARD_IUNKNOWN()
@ -28,8 +29,10 @@ public:
virtual HRESULT SetMenu (IAvnMenu* menu) override;
virtual HRESULT SetIsVisible (bool isVisible) override;
virtual HRESULT SetToolTipText (char* text) override;
virtual HRESULT SetIsTemplateIcon (bool isTemplateIcon) override;
};
#endif /* trayicon_h */

22
native/Avalonia.Native/src/OSX/trayicon.mm

@ -45,6 +45,7 @@ HRESULT AvnTrayIcon::SetIcon (void* data, size_t length)
size.width = originalSize.width * scaleFactor;
[image setSize: size];
[image setTemplate: _isTemplateIcon];
[_native setImage:image];
}
else
@ -98,3 +99,24 @@ HRESULT AvnTrayIcon::SetToolTipText(char* text)
return S_OK;
}
HRESULT AvnTrayIcon::SetIsTemplateIcon(bool isTemplateIcon)
{
START_COM_CALL;
@autoreleasepool
{
if (_isTemplateIcon != isTemplateIcon)
{
_isTemplateIcon = isTemplateIcon;
NSImage *image = [_native image];
if (image)
{
[image setTemplate: _isTemplateIcon];
}
}
}
return S_OK;
}

2
samples/ControlCatalog/App.xaml

@ -64,7 +64,7 @@
</Application.Styles>
<TrayIcon.Icons>
<TrayIcons>
<TrayIcon Icon="/Assets/test_icon.ico" ToolTipText="Avalonia Tray Icon ToolTip">
<TrayIcon Icon="/Assets/test_icon.ico" MacOSProperties.IsTemplateIcon="true" ToolTipText="Avalonia Tray Icon ToolTip">
<TrayIcon.Menu>
<NativeMenu>
<NativeMenuItem Header="Settings">

9
src/Avalonia.Controls/Platform/ITrayIconImpl.cs

@ -32,4 +32,13 @@ namespace Avalonia.Platform
/// </summary>
Action? OnClicked { get; set; }
}
[Unstable]
public interface ITrayIconWithIsTemplateImpl : ITrayIconImpl
{
/// <summary>
/// Sets if the tray icon has a template/monochrome icon or not.
/// </summary>
void SetIsTemplateIcon(bool isTemplateIcon);
}
}

35
src/Avalonia.Controls/Platform/MacOSProperties.cs

@ -0,0 +1,35 @@
using Avalonia.Platform;
namespace Avalonia.Controls;
/// <summary>
/// Set of MacOS specific attached properties that allow deeper customization of the application per platform.
/// </summary>
public class MacOSProperties
{
static MacOSProperties()
{
IsTemplateIconProperty.Changed.AddClassHandler<TrayIcon>(TrayIconIsTemplateIconChanged);
}
/// <summary>
/// Defines the IsTemplateIcon attached property.
/// </summary>
public static readonly AttachedProperty<bool> IsTemplateIconProperty =
AvaloniaProperty.RegisterAttached<MacOSProperties, TrayIcon, bool>("IsTemplateIcon");
/// <summary>
/// A Boolean value that determines whether the TrayIcon image represents a template image.
/// </summary>
public static void SetIsTemplateIcon(TrayIcon obj, bool value) => obj.SetValue(IsTemplateIconProperty, value);
/// <summary>
/// Returns a Boolean value that indicates whether the TrayIcon image is a template image.
/// </summary>
public static bool GetIsTemplateIcon(TrayIcon obj) => obj.GetValue(IsTemplateIconProperty);
private static void TrayIconIsTemplateIconChanged(TrayIcon trayIcon, AvaloniaPropertyChangedEventArgs args)
{
(trayIcon.Impl as ITrayIconWithIsTemplateImpl)?.SetIsTemplateIcon(args.GetNewValue<bool>());
}
}

2
src/Avalonia.Controls/TrayIcon.cs

@ -182,6 +182,8 @@ namespace Avalonia.Controls
public INativeMenuExporter? NativeMenuExporter => _impl?.MenuExporter;
internal ITrayIconImpl? Impl => _impl;
private static void Lifetime_Exit(object? sender, ControlledApplicationLifetimeExitEventArgs e)
{
var app = Application.Current ?? throw new InvalidOperationException("Application not yet initialized.");

7
src/Avalonia.Native/TrayIconImpl.cs

@ -8,7 +8,7 @@ using Avalonia.Platform;
namespace Avalonia.Native
{
internal class TrayIconImpl : ITrayIconImpl
internal class TrayIconImpl : ITrayIconWithIsTemplateImpl
{
private readonly IAvnTrayIcon _native;
@ -58,6 +58,11 @@ namespace Avalonia.Native
_native.SetIsVisible(visible.AsComBool());
}
public void SetIsTemplateIcon(bool isTemplateIcon)
{
_native.SetIsTemplateIcon(isTemplateIcon.AsComBool());
}
public INativeMenuExporter? MenuExporter { get; }
}
}

1
src/Avalonia.Native/avn.idl

@ -1000,6 +1000,7 @@ interface IAvnTrayIcon : IUnknown
HRESULT SetMenu(IAvnMenu* menu);
HRESULT SetIsVisible(bool isVisible);
HRESULT SetToolTipText(char* text);
HRESULT SetIsTemplateIcon(bool text);
}
[uuid(a7724dc1-cf6b-4fa8-9d23-228bf2593edc)]

2
src/Windows/Avalonia.Win32/TrayIconImpl.cs

@ -104,7 +104,7 @@ namespace Avalonia.Win32
{
UpdateIcon(!visible);
}
/// <inheritdoc />
public void SetToolTipText(string? text)
{

Loading…
Cancel
Save