Browse Source

Merge pull request #4 from AvaloniaUI/features/popup-implementation

implement popups.
pull/1977/head
danwalmsley 7 years ago
committed by GitHub
parent
commit
a09c365c76
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      src/Avalonia.Native.OSX/common.h
  2. 50
      src/Avalonia.Native.OSX/main.mm
  3. 118
      src/Avalonia.Native.OSX/window.mm
  4. 8
      src/Avalonia.Native/Avalonia.Native.csproj
  5. 4
      src/Avalonia.Native/AvaloniaNativePlatform.cs
  6. 18
      src/Avalonia.Native/Helpers.cs
  7. 27
      src/Avalonia.Native/PopupImpl.cs
  8. 52
      src/Avalonia.Native/WindowImplBase.cs
  9. 29
      src/headers/avalonia-native.h

5
src/Avalonia.Native.OSX/common.h

@ -9,4 +9,9 @@
extern IAvnPlatformThreadingInterface* CreatePlatformThreading();
extern IAvnWindow* CreateAvnWindow(IAvnWindowEvents*events);
extern IAvnPopup* CreateAvnPopup(IAvnWindowEvents*events);
extern NSPoint ToNSPoint (AvnPoint p);
extern AvnPoint ToAvnPoint (NSPoint p);
extern AvnPoint ConvertPointY (AvnPoint p);
#endif

50
src/Avalonia.Native.OSX/main.mm

@ -80,14 +80,62 @@ public:
return S_OK;
};
virtual HRESULT CreatePopup(IAvnWindowEvents* cb, IAvnPopup** ppv)
{
if(cb == nullptr || ppv == nullptr)
return E_POINTER;
*ppv = CreateAvnPopup(cb);
return S_OK;
}
virtual HRESULT CreatePlatformThreadingInterface(IAvnPlatformThreadingInterface** ppv)
{
*ppv = CreatePlatformThreading();
return S_OK;
};
}
};
extern "C" IAvaloniaNativeFactory* CreateAvaloniaNative()
{
return new AvaloniaNative();
};
NSPoint ToNSPoint (AvnPoint p)
{
@autoreleasepool
{
NSPoint result;
result.x = p.X;
result.y = p.Y;
return result;
}
}
AvnPoint ToAvnPoint (NSPoint p)
{
@autoreleasepool
{
AvnPoint result;
result.X = p.x;
result.Y = p.y;
return result;
}
}
AvnPoint ConvertPointY (AvnPoint p)
{
@autoreleasepool
{
auto sw = [NSScreen.screens objectAtIndex:0].frame;
auto t = MAX(sw.origin.y, sw.origin.y + sw.size.height);
p.Y = t - p.Y;
return p;
}
}

118
src/Avalonia.Native.OSX/window.mm

@ -3,8 +3,9 @@
class WindowBaseImpl;
@interface AvnView : NSView
-(AvnView*) initWithParent: (WindowBaseImpl*) parent;
-(NSEvent*) lastMouseDownEvent;
-(AvnView*) initWithParent: (WindowBaseImpl*) parent;
-(NSEvent*) lastMouseDownEvent;
-(AvnPoint) translateLocalPoint:(AvnPoint)pt;
@end
@interface AvnWindow : NSWindow <NSWindowDelegate>
@ -18,11 +19,16 @@ public:
AvnView* View;
AvnWindow* Window;
ComPtr<IAvnWindowBaseEvents> BaseEvents;
AvnPoint lastPositionSet;
WindowBaseImpl(IAvnWindowBaseEvents* events)
{
BaseEvents = events;
View = [[AvnView alloc] initWithParent:this];
Window = [[AvnWindow alloc] initWithParent:this];
lastPositionSet.X = 100;
lastPositionSet.Y = 100;
[Window setStyleMask:NSWindowStyleMaskBorderless];
[Window setBackingType:NSBackingStoreBuffered];
[Window setContentView: View];
@ -30,11 +36,21 @@ public:
virtual HRESULT Show()
{
SetPosition(lastPositionSet);
UpdateStyle();
[Window makeKeyAndOrderFront:Window];
return S_OK;
}
virtual HRESULT Hide ()
{
if(Window != nullptr)
{
[Window orderOut:Window];
}
return S_OK;
}
virtual HRESULT Close()
{
[Window close];
@ -51,6 +67,21 @@ public:
return S_OK;
}
virtual HRESULT GetScaling (double* ret)
{
if(ret == nullptr)
return E_POINTER;
if(Window == nullptr)
{
*ret = 1;
return S_OK;
}
*ret = [Window backingScaleFactor];
return S_OK;
}
virtual HRESULT Resize(double x, double y)
{
[Window setContentSize:NSSize{x, y}];
@ -74,6 +105,59 @@ public:
[Window performWindowDragWithEvent:lastEvent];
}
virtual HRESULT GetPosition (AvnPoint* ret)
{
if(ret == nullptr)
{
return E_POINTER;
}
auto frame = [Window frame];
ret->X = frame.origin.x;
ret->Y = frame.origin.y + frame.size.height;
*ret = ConvertPointY(*ret);
return S_OK;
}
virtual void SetPosition (AvnPoint point)
{
lastPositionSet = point;
[Window setFrameTopLeftPoint:ToNSPoint(ConvertPointY(point))];
}
virtual HRESULT PointToClient (AvnPoint point, AvnPoint* ret)
{
if(ret == nullptr)
{
return E_POINTER;
}
point = ConvertPointY(point);
auto viewPoint = [Window convertPointFromScreen:ToNSPoint(point)];
*ret = [View translateLocalPoint:ToAvnPoint(viewPoint)];
return S_OK;
}
virtual HRESULT PointToScreen (AvnPoint point, AvnPoint* ret)
{
if(ret == nullptr)
{
return E_POINTER;
}
auto cocoaViewPoint = ToNSPoint([View translateLocalPoint:point]);
auto cocoaScreenPoint = [Window convertPointToScreen:cocoaViewPoint];
*ret = ConvertPointY(ToAvnPoint(cocoaScreenPoint));
return S_OK;
}
protected:
virtual NSWindowStyleMask GetStyle()
{
@ -160,7 +244,7 @@ protected:
free(ptr);
}
- (AvnPoint)translateLocalPoint:(AvnPoint)pt
- (AvnPoint) translateLocalPoint:(AvnPoint)pt
{
pt.Y = [self bounds].size.height - pt.Y;
return pt;
@ -194,7 +278,6 @@ protected:
}
}
auto timestamp = [event timestamp] * 1000;
auto modifiers = [self getModifiers:[event modifierFlags]];
@ -368,6 +451,32 @@ protected:
@end
class PopupImpl : public WindowBaseImpl, public IAvnPopup
{
private:
BEGIN_INTERFACE_MAP()
INHERIT_INTERFACE_MAP(WindowBaseImpl)
INTERFACE_MAP_ENTRY(IAvnPopup, IID_IAvnPopup)
END_INTERFACE_MAP()
ComPtr<IAvnWindowEvents> WindowEvents;
PopupImpl(IAvnWindowEvents* events) : WindowBaseImpl(events)
{
WindowEvents = events;
[Window setLevel:NSPopUpMenuWindowLevel];
}
protected:
virtual NSWindowStyleMask GetStyle()
{
return NSWindowStyleMaskBorderless;
}
};
extern IAvnPopup* CreateAvnPopup(IAvnWindowEvents*events)
{
IAvnPopup* ptr = dynamic_cast<IAvnPopup*>(new PopupImpl(events));
return ptr;
}
class WindowImpl : public WindowBaseImpl, public IAvnWindow
{
@ -413,7 +522,6 @@ protected:
}
};
extern IAvnWindow* CreateAvnWindow(IAvnWindowEvents*events)
{
IAvnWindow* ptr = dynamic_cast<IAvnWindow*>(new WindowImpl(events));

8
src/Avalonia.Native/Avalonia.Native.csproj

@ -12,4 +12,12 @@
<PackageReference Include="Avalonia" Version="0.6.2-build6248-beta" />
<SharpGenMapping Include="Mappings.xml" />
</ItemGroup>
<ItemGroup>
<Compile Remove="Generated\LocalInterop.cs" />
<Compile Remove="Generated\Structures.cs" />
<Compile Remove="Generated\Functions.cs" />
<Compile Remove="Generated\Interfaces.cs" />
<Compile Remove="Generated\LocalInterop.cs" />
<Compile Remove="Generated\Structures.cs" />
</ItemGroup>
</Project>

4
src/Avalonia.Native/AvaloniaNativePlatform.cs

@ -88,8 +88,8 @@ namespace Avalonia.Native
}
public IPopupImpl CreatePopup()
{
throw new NotImplementedException();
{
return new PopupImpl(_factory);
}
}

18
src/Avalonia.Native/Helpers.cs

@ -0,0 +1,18 @@
using System;
using Avalonia.Native.Interop;
namespace Avalonia.Native
{
public static class Helpers
{
public static Point ToAvaloniaPoint (this AvnPoint pt)
{
return new Point(pt.X, pt.Y);
}
public static AvnPoint ToAvnPoint (this Point pt)
{
return new AvnPoint { X = pt.X, Y = pt.Y };
}
}
}

27
src/Avalonia.Native/PopupImpl.cs

@ -0,0 +1,27 @@
using System;
using Avalonia.Native.Interop;
using Avalonia.Platform;
namespace Avalonia.Native
{
public class PopupImpl : WindowBaseImpl, IPopupImpl
{
IAvnPopup _native;
public PopupImpl(IAvaloniaNativeFactory factory)
{
using (var e = new PopupEvents(this))
Init(_native = factory.CreatePopup(e));
}
class PopupEvents : WindowBaseEvents, IAvnWindowEvents
{
readonly PopupImpl _parent;
public PopupEvents(PopupImpl parent) : base(parent)
{
_parent = parent;
}
}
}
}

52
src/Avalonia.Native/WindowImplBase.cs

@ -118,11 +118,11 @@ namespace Avalonia.Native
switch (type)
{
case AvnRawMouseEventType.Wheel:
Input?.Invoke(new RawMouseWheelEventArgs(_mouse, timeStamp, _inputRoot, new Point(point.X, point.Y), new Vector(delta.X, delta.Y), (InputModifiers)modifiers));
Input?.Invoke(new RawMouseWheelEventArgs(_mouse, timeStamp, _inputRoot, point.ToAvaloniaPoint(), new Vector(delta.X, delta.Y), (InputModifiers)modifiers));
break;
default:
Input?.Invoke(new RawMouseEventArgs(_mouse, timeStamp, _inputRoot, (RawMouseEventType)type, new Point(point.X, point.Y), (InputModifiers)modifiers));
Input?.Invoke(new RawMouseEventArgs(_mouse, timeStamp, _inputRoot, (RawMouseEventType)type, point.ToAvaloniaPoint(), (InputModifiers)modifiers));
break;
}
}
@ -164,10 +164,35 @@ namespace Avalonia.Native
}
public Point Position
{
get => _native.GetPosition().ToAvaloniaPoint();
set => _native.SetPosition(value.ToAvnPoint());
}
public Point PointToClient(Point point)
{
return _native.PointToClient(point.ToAvnPoint()).ToAvaloniaPoint();
}
public Point PointToScreen(Point point)
{
return _native.PointToScreen(point.ToAvnPoint()).ToAvaloniaPoint();
}
public void Hide()
{
_native.Hide();
}
public void BeginMoveDrag()
{
_native.BeginMoveDrag();
}
#region Stubs
public double Scaling => 1;
public double Scaling => _native.GetScaling();
public Point Position { get; set; }
public Action<Point> PositionChanged { get; set; }
public Action Deactivated { get; set; }
public Action Activated { get; set; }
@ -195,29 +220,10 @@ namespace Avalonia.Native
{
}
public void Hide()
{
}
public void BeginMoveDrag()
{
_native.BeginMoveDrag();
}
public void BeginResizeDrag(WindowEdge edge)
{
}
public Point PointToClient(Point point)
{
return point;
}
public Point PointToScreen(Point point)
{
return point;
}
#endregion
}
}

29
src/headers/avalonia-native.h

@ -4,6 +4,7 @@
struct IAvnWindowEvents;
struct IAvnWindow;
struct IAvnPopup;
struct IAvnMacOptions;
struct IAvnPlatformThreadingInterface;
@ -59,26 +60,38 @@ public:
virtual HRESULT Initialize() = 0;
virtual IAvnMacOptions* GetMacOptions() = 0;
virtual HRESULT CreateWindow(IAvnWindowEvents* cb, IAvnWindow** ppv) = 0;
virtual HRESULT CreatePopup (IAvnWindowEvents* cb, IAvnPopup** ppv) = 0;
virtual HRESULT CreatePlatformThreadingInterface(IAvnPlatformThreadingInterface** ppv) = 0;
};
AVNCOM(IAvnWindowBase, 02) : virtual IUnknown
{
virtual HRESULT Show() = 0;
virtual HRESULT Hide () = 0;
virtual HRESULT Close() = 0;
virtual HRESULT GetClientSize(AvnSize*ret) = 0;
virtual HRESULT GetScaling(double*ret)=0;
virtual HRESULT Resize(double width, double height) = 0;
virtual void Invalidate (AvnRect rect) = 0;
virtual void BeginMoveDrag () = 0;
virtual HRESULT GetPosition (AvnPoint*ret) = 0;
virtual void SetPosition (AvnPoint point) = 0;
virtual HRESULT PointToClient (AvnPoint point, AvnPoint*ret) = 0;
virtual HRESULT PointToScreen (AvnPoint point, AvnPoint*ret) = 0;
};
AVNCOM(IAvnWindow, 03) : virtual IAvnWindowBase
AVNCOM(IAvnPopup, 03) : virtual IAvnWindowBase
{
};
AVNCOM(IAvnWindow, 04) : virtual IAvnWindowBase
{
virtual HRESULT SetCanResize(bool value) = 0;
virtual HRESULT SetHasDecorations(bool value) = 0;
};
AVNCOM(IAvnWindowBaseEvents, 04) : IUnknown
AVNCOM(IAvnWindowBaseEvents, 05) : IUnknown
{
virtual HRESULT SoftwareDraw(void* ptr, int stride, int pixelWidth, int pixelHeight, const AvnSize& logicalSize) = 0;
virtual void Closed() = 0;
@ -93,33 +106,33 @@ AVNCOM(IAvnWindowBaseEvents, 04) : IUnknown
};
AVNCOM(IAvnWindowEvents, 05) : IAvnWindowBaseEvents
AVNCOM(IAvnWindowEvents, 06) : IAvnWindowBaseEvents
{
};
AVNCOM(IAvnMacOptions, 06) : virtual IUnknown
AVNCOM(IAvnMacOptions, 07) : virtual IUnknown
{
virtual HRESULT SetShowInDock(int show) = 0;
};
AVNCOM(IAvnActionCallback, 07) : IUnknown
AVNCOM(IAvnActionCallback, 08) : IUnknown
{
virtual void Run() = 0;
};
AVNCOM(IAvnSignaledCallback, 08) : IUnknown
AVNCOM(IAvnSignaledCallback, 09) : IUnknown
{
virtual void Signaled(int priority, bool priorityContainsMeaningfulValue) = 0;
};
AVNCOM(IAvnLoopCancellation, 09) : virtual IUnknown
AVNCOM(IAvnLoopCancellation, 0a) : virtual IUnknown
{
virtual void Cancel() = 0;
};
AVNCOM(IAvnPlatformThreadingInterface, 0a) : virtual IUnknown
AVNCOM(IAvnPlatformThreadingInterface, 0b) : virtual IUnknown
{
virtual bool GetCurrentThreadIsLoopThread() = 0;
virtual void SetSignaledCallback(IAvnSignaledCallback* cb) = 0;

Loading…
Cancel
Save