Browse Source

Merge branch 'Flyouts' of https://github.com/amwx/Avalonia into Flyouts

pull/5682/head
amwx 6 years ago
parent
commit
6b9d87fb04
  1. 2
      native/Avalonia.Native/src/OSX/common.h
  2. 4
      native/Avalonia.Native/src/OSX/main.mm
  3. 9
      native/Avalonia.Native/src/OSX/menu.h
  4. 34
      native/Avalonia.Native/src/OSX/menu.mm
  5. 7
      native/Avalonia.Native/src/OSX/window.mm
  6. 4
      nukebuild/Build.cs
  7. 4
      samples/ControlCatalog/MainWindow.xaml
  8. 4
      src/Avalonia.Controls/ApiCompatBaseline.txt
  9. 2
      src/Avalonia.Controls/INativeMenuExporterEventsImplBridge.cs
  10. 33
      src/Avalonia.Controls/NativeMenu.cs
  11. 16
      src/Avalonia.Controls/NativeMenuItemSeparator.cs
  12. 10
      src/Avalonia.Controls/NativeMenuItemSeperator.cs
  13. 2
      src/Avalonia.FreeDesktop/DBusMenuExporter.cs
  14. 26
      src/Avalonia.Native/IAvnMenu.cs
  15. 7
      src/Avalonia.Native/avn.idl

2
native/Avalonia.Native/src/OSX/common.h

@ -23,7 +23,7 @@ extern IAvnCursorFactory* CreateCursorFactory();
extern IAvnGlDisplay* GetGlDisplay(); extern IAvnGlDisplay* GetGlDisplay();
extern IAvnMenu* CreateAppMenu(IAvnMenuEvents* events); extern IAvnMenu* CreateAppMenu(IAvnMenuEvents* events);
extern IAvnMenuItem* CreateAppMenuItem(); extern IAvnMenuItem* CreateAppMenuItem();
extern IAvnMenuItem* CreateAppMenuItemSeperator(); extern IAvnMenuItem* CreateAppMenuItemSeparator();
extern IAvnNativeControlHost* CreateNativeControlHost(NSView* parent); extern IAvnNativeControlHost* CreateNativeControlHost(NSView* parent);
extern void SetAppMenu (NSString* appName, IAvnMenu* appMenu); extern void SetAppMenu (NSString* appName, IAvnMenu* appMenu);
extern IAvnMenu* GetAppMenu (); extern IAvnMenu* GetAppMenu ();

4
native/Avalonia.Native/src/OSX/main.mm

@ -253,9 +253,9 @@ public:
return S_OK; return S_OK;
} }
virtual HRESULT CreateMenuItemSeperator (IAvnMenuItem** ppv) override virtual HRESULT CreateMenuItemSeparator (IAvnMenuItem** ppv) override
{ {
*ppv = ::CreateAppMenuItemSeperator(); *ppv = ::CreateAppMenuItemSeparator();
return S_OK; return S_OK;
} }

9
native/Avalonia.Native/src/OSX/menu.h

@ -31,13 +31,13 @@ private:
NSMenuItem* _native; // here we hold a pointer to an AvnMenuItem NSMenuItem* _native; // here we hold a pointer to an AvnMenuItem
IAvnActionCallback* _callback; IAvnActionCallback* _callback;
IAvnPredicateCallback* _predicate; IAvnPredicateCallback* _predicate;
bool _isSeperator; bool _isSeparator;
bool _isCheckable; bool _isCheckable;
public: public:
FORWARD_IUNKNOWN() FORWARD_IUNKNOWN()
AvnAppMenuItem(bool isSeperator); AvnAppMenuItem(bool isSeparator);
NSMenuItem* GetNative(); NSMenuItem* GetNative();
@ -60,7 +60,6 @@ public:
void RaiseOnClicked(); void RaiseOnClicked();
}; };
class AvnAppMenu : public ComSingleObject<IAvnMenu, &IID_IAvnMenu> class AvnAppMenu : public ComSingleObject<IAvnMenu, &IID_IAvnMenu>
{ {
private: private:
@ -71,10 +70,12 @@ public:
FORWARD_IUNKNOWN() FORWARD_IUNKNOWN()
AvnAppMenu(IAvnMenuEvents* events); AvnAppMenu(IAvnMenuEvents* events);
AvnMenu* GetNative(); AvnMenu* GetNative();
void RaiseNeedsUpdate (); void RaiseNeedsUpdate ();
void RaiseOpening();
void RaiseClosed();
virtual HRESULT InsertItem (int index, IAvnMenuItem* item) override; virtual HRESULT InsertItem (int index, IAvnMenuItem* item) override;

34
native/Avalonia.Native/src/OSX/menu.mm

@ -71,12 +71,12 @@
} }
@end @end
AvnAppMenuItem::AvnAppMenuItem(bool isSeperator) AvnAppMenuItem::AvnAppMenuItem(bool isSeparator)
{ {
_isCheckable = false; _isCheckable = false;
_isSeperator = isSeperator; _isSeparator = isSeparator;
if(isSeperator) if(isSeparator)
{ {
_native = [NSMenuItem separatorItem]; _native = [NSMenuItem separatorItem];
} }
@ -298,6 +298,23 @@ void AvnAppMenu::RaiseNeedsUpdate()
} }
} }
void AvnAppMenu::RaiseOpening()
{
if(_baseEvents != nullptr)
{
_baseEvents->Opening();
}
}
void AvnAppMenu::RaiseClosed()
{
if(_baseEvents != nullptr)
{
_baseEvents->Closed();
}
}
HRESULT AvnAppMenu::InsertItem(int index, IAvnMenuItem *item) HRESULT AvnAppMenu::InsertItem(int index, IAvnMenuItem *item)
{ {
@autoreleasepool @autoreleasepool
@ -382,6 +399,15 @@ HRESULT AvnAppMenu::Clear()
_parent->RaiseNeedsUpdate(); _parent->RaiseNeedsUpdate();
} }
- (void)menuWillOpen:(NSMenu *)menu
{
_parent->RaiseOpening();
}
- (void)menuDidClose:(NSMenu *)menu
{
_parent->RaiseClosed();
}
@end @end
@ -401,7 +427,7 @@ extern IAvnMenuItem* CreateAppMenuItem()
} }
} }
extern IAvnMenuItem* CreateAppMenuItemSeperator() extern IAvnMenuItem* CreateAppMenuItemSeparator()
{ {
@autoreleasepool @autoreleasepool
{ {

7
native/Avalonia.Native/src/OSX/window.mm

@ -2231,9 +2231,12 @@ protected:
{ {
@autoreleasepool @autoreleasepool
{ {
[Window setContentSize:NSSize{x, y}]; if (Window != nullptr)
{
[Window setContentSize:NSSize{x, y}];
[Window setFrameTopLeftPoint:ToNSPoint(ConvertPointY(lastPositionSet))]; [Window setFrameTopLeftPoint:ToNSPoint(ConvertPointY(lastPositionSet))];
}
return S_OK; return S_OK;
} }

4
nukebuild/Build.cs

@ -89,10 +89,6 @@ partial class Build : NukeBuild
Process.Start(new ProcessStartInfo(command, args) {UseShellExecute = false}).WaitForExit(); Process.Start(new ProcessStartInfo(command, args) {UseShellExecute = false}).WaitForExit();
} }
ExecWait("dotnet version:", "dotnet", "--version"); ExecWait("dotnet version:", "dotnet", "--version");
if (Parameters.IsRunningOnUnix)
ExecWait("Mono version:", "mono", "--version");
} }
IReadOnlyCollection<Output> MsBuildCommon( IReadOnlyCollection<Output> MsBuildCommon(

4
samples/ControlCatalog/MainWindow.xaml

@ -18,11 +18,11 @@
<NativeMenuItem Header="File"> <NativeMenuItem Header="File">
<NativeMenu> <NativeMenu>
<NativeMenuItem Icon="/Assets/test_icon.ico" Header="Open" Clicked="OnOpenClicked" Gesture="Ctrl+O"/> <NativeMenuItem Icon="/Assets/test_icon.ico" Header="Open" Clicked="OnOpenClicked" Gesture="Ctrl+O"/>
<NativeMenuItemSeperator/> <NativeMenuItemSeperator/><!-- Uses incorrect spelling to demonstrate backwards compatibility -->
<NativeMenuItem Icon="/Assets/github_icon.png" Header="Recent"> <NativeMenuItem Icon="/Assets/github_icon.png" Header="Recent">
<NativeMenu/> <NativeMenu/>
</NativeMenuItem> </NativeMenuItem>
<NativeMenuItemSeperator/> <NativeMenuItemSeparator/>
<NativeMenuItem Header="{x:Static local:MainWindow.MenuQuitHeader}" <NativeMenuItem Header="{x:Static local:MainWindow.MenuQuitHeader}"
Gesture="{x:Static local:MainWindow.MenuQuitGesture}" Gesture="{x:Static local:MainWindow.MenuQuitGesture}"
Clicked="OnCloseClicked" /> Clicked="OnCloseClicked" />

4
src/Avalonia.Controls/ApiCompatBaseline.txt

@ -1,7 +1,9 @@
Compat issues with assembly Avalonia.Controls: Compat issues with assembly Avalonia.Controls:
InterfacesShouldHaveSameMembers : Interface member 'public void Avalonia.Controls.INativeMenuExporterEventsImplBridge.RaiseClosed()' is present in the implementation but not in the contract.
InterfacesShouldHaveSameMembers : Interface member 'public void Avalonia.Controls.INativeMenuExporterEventsImplBridge.RaiseOpening()' is present in the implementation but not in the contract.
MembersMustExist : Member 'public void Avalonia.Controls.Embedding.Offscreen.OffscreenTopLevelImplBase.SetCursor(Avalonia.Platform.IPlatformHandle)' does not exist in the implementation but it does exist in the contract. MembersMustExist : Member 'public void Avalonia.Controls.Embedding.Offscreen.OffscreenTopLevelImplBase.SetCursor(Avalonia.Platform.IPlatformHandle)' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'public Avalonia.AvaloniaProperty Avalonia.AvaloniaProperty Avalonia.Controls.Notifications.NotificationCard.CloseOnClickProperty' does not exist in the implementation but it does exist in the contract. MembersMustExist : Member 'public Avalonia.AvaloniaProperty Avalonia.AvaloniaProperty Avalonia.Controls.Notifications.NotificationCard.CloseOnClickProperty' does not exist in the implementation but it does exist in the contract.
InterfacesShouldHaveSameMembers : Interface member 'public void Avalonia.Platform.ITopLevelImpl.SetCursor(Avalonia.Platform.ICursorImpl)' is present in the implementation but not in the contract. InterfacesShouldHaveSameMembers : Interface member 'public void Avalonia.Platform.ITopLevelImpl.SetCursor(Avalonia.Platform.ICursorImpl)' is present in the implementation but not in the contract.
InterfacesShouldHaveSameMembers : Interface member 'public void Avalonia.Platform.ITopLevelImpl.SetCursor(Avalonia.Platform.IPlatformHandle)' is present in the contract but not in the implementation. InterfacesShouldHaveSameMembers : Interface member 'public void Avalonia.Platform.ITopLevelImpl.SetCursor(Avalonia.Platform.IPlatformHandle)' is present in the contract but not in the implementation.
MembersMustExist : Member 'public void Avalonia.Platform.ITopLevelImpl.SetCursor(Avalonia.Platform.IPlatformHandle)' does not exist in the implementation but it does exist in the contract. MembersMustExist : Member 'public void Avalonia.Platform.ITopLevelImpl.SetCursor(Avalonia.Platform.IPlatformHandle)' does not exist in the implementation but it does exist in the contract.
Total Issues: 5 Total Issues: 7

2
src/Avalonia.Controls/INativeMenuExporterEventsImplBridge.cs

@ -3,5 +3,7 @@ namespace Avalonia.Controls
public interface INativeMenuExporterEventsImplBridge public interface INativeMenuExporterEventsImplBridge
{ {
void RaiseNeedsUpdate (); void RaiseNeedsUpdate ();
void RaiseOpening();
void RaiseClosed();
} }
} }

33
src/Avalonia.Controls/NativeMenu.cs

@ -12,13 +12,34 @@ namespace Avalonia.Controls
private readonly AvaloniaList<NativeMenuItemBase> _items = private readonly AvaloniaList<NativeMenuItemBase> _items =
new AvaloniaList<NativeMenuItemBase> { ResetBehavior = ResetBehavior.Remove }; new AvaloniaList<NativeMenuItemBase> { ResetBehavior = ResetBehavior.Remove };
private NativeMenuItem _parent; private NativeMenuItem _parent;
[Content] [Content]
public IList<NativeMenuItemBase> Items => _items; public IList<NativeMenuItemBase> Items => _items;
/// <summary> /// <summary>
/// Raised when the user clicks the menu and before its opened. Use this event to update the menu dynamically. /// Raised when the menu requests an update.
/// </summary>
/// <remarks>
/// Use this event to add, remove or modify menu items before a menu is
/// shown or a hotkey is pressed.
/// </remarks>
public event EventHandler<EventArgs> NeedsUpdate;
/// <summary>
/// Raised before the menu is opened.
/// </summary> /// </summary>
/// <remarks>
/// Do not update the menu in this event; use <see cref="NeedsUpdate"/>.
/// </remarks>
public event EventHandler<EventArgs> Opening; public event EventHandler<EventArgs> Opening;
/// <summary>
/// Raised after the menu is closed.
/// </summary>
/// <remarks>
/// Do not update the menu in this event; use <see cref="NeedsUpdate"/>.
/// </remarks>
public event EventHandler<EventArgs> Closed;
public NativeMenu() public NativeMenu()
{ {
@ -27,10 +48,20 @@ namespace Avalonia.Controls
} }
void INativeMenuExporterEventsImplBridge.RaiseNeedsUpdate() void INativeMenuExporterEventsImplBridge.RaiseNeedsUpdate()
{
NeedsUpdate?.Invoke(this, EventArgs.Empty);
}
void INativeMenuExporterEventsImplBridge.RaiseOpening()
{ {
Opening?.Invoke(this, EventArgs.Empty); Opening?.Invoke(this, EventArgs.Empty);
} }
void INativeMenuExporterEventsImplBridge.RaiseClosed()
{
Closed?.Invoke(this, EventArgs.Empty);
}
private void Validator(NativeMenuItemBase obj) private void Validator(NativeMenuItemBase obj)
{ {
if (obj.Parent != null) if (obj.Parent != null)

16
src/Avalonia.Controls/NativeMenuItemSeparator.cs

@ -0,0 +1,16 @@
using System;
namespace Avalonia.Controls
{
[Obsolete("This class exists to maintain backwards compatiblity with existing code. Use NativeMenuItemSeparator instead")]
public class NativeMenuItemSeperator : NativeMenuItemSeparator
{
}
public class NativeMenuItemSeparator : NativeMenuItemBase
{
[Obsolete("This is a temporary hack to make our MenuItem recognize this as a separator, don't use", true)]
public string Header => "-";
}
}

10
src/Avalonia.Controls/NativeMenuItemSeperator.cs

@ -1,10 +0,0 @@
using System;
namespace Avalonia.Controls
{
public class NativeMenuItemSeperator : NativeMenuItemBase
{
[Obsolete("This is a temporary hack to make our MenuItem recognize this as a separator, don't use", true)]
public string Header => "-";
}
}

2
src/Avalonia.FreeDesktop/DBusMenuExporter.cs

@ -192,7 +192,7 @@ namespace Avalonia.FreeDesktop
{ {
var (it, menu) = i; var (it, menu) = i;
if (it is NativeMenuItemSeperator) if (it is NativeMenuItemSeparator)
{ {
if (name == "type") if (name == "type")
return "separator"; return "separator";

26
src/Avalonia.Native/IAvnMenu.cs

@ -20,11 +20,23 @@ namespace Avalonia.Native.Interop
{ {
_parent?.RaiseNeedsUpdate(); _parent?.RaiseNeedsUpdate();
} }
public void Opening()
{
_parent?.RaiseOpening();
}
public void Closed()
{
_parent?.RaiseClosed();
}
} }
partial interface IAvnMenu partial interface IAvnMenu
{ {
void RaiseNeedsUpdate(); void RaiseNeedsUpdate();
void RaiseOpening();
void RaiseClosed();
void Deinitialise(); void Deinitialise();
} }
} }
@ -45,6 +57,16 @@ namespace Avalonia.Native.Interop.Impl
_exporter.UpdateIfNeeded(); _exporter.UpdateIfNeeded();
} }
public void RaiseOpening()
{
(ManagedMenu as INativeMenuExporterEventsImplBridge).RaiseOpening();
}
public void RaiseClosed()
{
(ManagedMenu as INativeMenuExporterEventsImplBridge).RaiseClosed();
}
internal NativeMenu ManagedMenu { get; private set; } internal NativeMenu ManagedMenu { get; private set; }
public static __MicroComIAvnMenuProxy Create(IAvaloniaNativeFactory factory) public static __MicroComIAvnMenuProxy Create(IAvaloniaNativeFactory factory)
@ -103,8 +125,8 @@ namespace Avalonia.Native.Interop.Impl
private __MicroComIAvnMenuItemProxy CreateNew(IAvaloniaNativeFactory factory, NativeMenuItemBase item) private __MicroComIAvnMenuItemProxy CreateNew(IAvaloniaNativeFactory factory, NativeMenuItemBase item)
{ {
var nativeItem = (__MicroComIAvnMenuItemProxy)(item is NativeMenuItemSeperator ? var nativeItem = (__MicroComIAvnMenuItemProxy)(item is NativeMenuItemSeparator ?
factory.CreateMenuItemSeperator() : factory.CreateMenuItemSeparator() :
factory.CreateMenuItem()); factory.CreateMenuItem());
nativeItem.ManagedMenuItem = item; nativeItem.ManagedMenuItem = item;

7
src/Avalonia.Native/avn.idl

@ -417,7 +417,7 @@ interface IAvaloniaNativeFactory : IUnknown
HRESULT SetAppMenu(IAvnMenu* menu); HRESULT SetAppMenu(IAvnMenu* menu);
HRESULT CreateMenu(IAvnMenuEvents* cb, IAvnMenu** ppv); HRESULT CreateMenu(IAvnMenuEvents* cb, IAvnMenu** ppv);
HRESULT CreateMenuItem(IAvnMenuItem** ppv); HRESULT CreateMenuItem(IAvnMenuItem** ppv);
HRESULT CreateMenuItemSeperator(IAvnMenuItem** ppv); HRESULT CreateMenuItemSeparator(IAvnMenuItem** ppv);
} }
[uuid(233e094f-9b9f-44a3-9a6e-6948bbdd9fb1)] [uuid(233e094f-9b9f-44a3-9a6e-6948bbdd9fb1)]
@ -685,10 +685,9 @@ interface IAvnMenuItem : IUnknown
[uuid(0af7df53-7632-42f4-a650-0992c361b477)] [uuid(0af7df53-7632-42f4-a650-0992c361b477)]
interface IAvnMenuEvents : IUnknown interface IAvnMenuEvents : IUnknown
{ {
/**
* NeedsUpdate
*/
void NeedsUpdate(); void NeedsUpdate();
void Opening();
void Closed();
} }
[uuid(5142bb41-66ab-49e7-bb37-cd079c000f27)] [uuid(5142bb41-66ab-49e7-bb37-cd079c000f27)]

Loading…
Cancel
Save