Browse Source

Refactoring SetCursor impl

pull/1977/head
ElBuda 8 years ago
parent
commit
a5f857874b
  1. 2
      src/Avalonia.Native.OSX/Avalonia.Native.OSX.xcodeproj/project.pbxproj
  2. 2
      src/Avalonia.Native.OSX/common.h
  3. 33
      src/Avalonia.Native.OSX/cursor.h
  4. 101
      src/Avalonia.Native.OSX/cursor.mm
  5. 4
      src/Avalonia.Native.OSX/main.mm
  6. 20
      src/Avalonia.Native.OSX/window.mm
  7. 2
      src/Avalonia.Native/AvaloniaNativePlatform.cs
  8. 25
      src/Avalonia.Native/Cursor.cs
  9. 4
      src/Avalonia.Native/WindowImplBase.cs
  10. 13
      src/headers/avalonia-native.h

2
src/Avalonia.Native.OSX/Avalonia.Native.OSX.xcodeproj/project.pbxproj

@ -27,6 +27,7 @@
37E2330E21583241000CB7E2 /* KeyTransform.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = KeyTransform.mm; sourceTree = "<group>"; };
5B21A981216530F500CEE36E /* cursor.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = cursor.mm; sourceTree = "<group>"; };
5B8BD94E215BFEA6005ED2A7 /* clipboard.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = clipboard.mm; sourceTree = "<group>"; };
5BF943652167AD1D009CAE35 /* cursor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = cursor.h; sourceTree = "<group>"; };
AB00E4F62147CA920032A60A /* main.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = main.mm; sourceTree = "<group>"; };
AB661C1D2148230F00291242 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
AB661C1F2148286E00291242 /* window.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = window.mm; sourceTree = "<group>"; };
@ -58,6 +59,7 @@
AB7A61E62147C814003C5833 = {
isa = PBXGroup;
children = (
5BF943652167AD1D009CAE35 /* cursor.h */,
5B21A981216530F500CEE36E /* cursor.mm */,
5B8BD94E215BFEA6005ED2A7 /* clipboard.mm */,
379A4506214D0F6500CC143D /* headers */,

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

@ -13,7 +13,7 @@ extern IAvnPopup* CreateAvnPopup(IAvnWindowEvents*events);
extern IAvnSystemDialogs* CreateSystemDialogs();
extern IAvnScreens* CreateScreens();
extern IAvnClipboard* CreateClipboard();
extern IAvnCursor* CreateCursor();
extern IAvnCursorFactory* CreateCursorFactory();
extern NSPoint ToNSPoint (AvnPoint p);
extern AvnPoint ToAvnPoint (NSPoint p);

33
src/Avalonia.Native.OSX/cursor.h

@ -0,0 +1,33 @@
//
// cursor.h
// Avalonia.Native.OSX
//
// Created by ElBuda on 10/5/18.
// Copyright © 2018 Avalonia. All rights reserved.
//
#ifndef cursor_h
#define cursor_h
#include "common.h"
#include <map>
class Cursor : public ComSingleObject<IAvnCursor, &IID_IAvnCursor>
{
private:
NSCursor * _native;
public:
Cursor(NSCursor * cursor)
{
_native = cursor;
}
NSCursor* GetNative()
{
return _native;
}
};
extern std::map<AvnStandardCursorType, Cursor*> s_cursorMap;
#endif /* cursor_h */

101
src/Avalonia.Native.OSX/cursor.mm

@ -1,67 +1,56 @@
#include "common.h"
#include "cursor.h"
#include <map>
class Cursor : public ComSingleObject<IAvnCursor, &IID_IAvnCursor>
class CursorFactory : public ComSingleObject<IAvnCursorFactory, &IID_IAvnCursorFactory>
{
Cursor * arrowCursor = new Cursor([NSCursor arrowCursor]);
Cursor * crossCursor = new Cursor([NSCursor crosshairCursor]);
Cursor * resizeUpCursor = new Cursor([NSCursor resizeUpCursor]);
Cursor * resizeDownCursor = new Cursor([NSCursor resizeDownCursor]);
Cursor * dragCopyCursor = new Cursor([NSCursor dragCopyCursor]);
Cursor * dragLinkCursor = new Cursor([NSCursor dragLinkCursor]);
Cursor * pointingHandCursor = new Cursor([NSCursor pointingHandCursor]);
Cursor * contextualMenuCursor = new Cursor([NSCursor contextualMenuCursor]);
Cursor * IBeamCursor = new Cursor([NSCursor IBeamCursor]);
Cursor * resizeLeftCursor = new Cursor([NSCursor resizeLeftCursor]);
Cursor * resizeRightCursor = new Cursor([NSCursor resizeRightCursor]);
Cursor * operationNotAllowedCursor = new Cursor([NSCursor operationNotAllowedCursor]);
std::map<AvnStandardCursorType, Cursor*> s_cursorMap =
{
{ CursorArrow, arrowCursor },
{ CursorAppStarting, arrowCursor },
{ CursorWait, arrowCursor },
{ CursorTopLeftCorner, crossCursor },
{ CursorTopRightCorner, crossCursor },
{ CursorBottomLeftCorner, crossCursor },
{ CursorBottomRightCorner, crossCursor },
{ CursorCross, crossCursor },
{ CursorSizeAll, crossCursor },
{ CursorTopSide, resizeUpCursor },
{ CursorUpArrow, resizeUpCursor },
{ CursorBottomSize, resizeDownCursor },
{ CursorDragCopy, dragCopyCursor },
{ CursorDragMove, dragCopyCursor },
{ CursorDragLink, dragLinkCursor },
{ CursorHand, pointingHandCursor },
{ CursorHelp, contextualMenuCursor },
{ CursorIbeam, IBeamCursor },
{ CursorLeftSide, resizeLeftCursor },
{ CursorRightSide, resizeRightCursor },
{ CursorNo, operationNotAllowedCursor }
};
public:
virtual HRESULT GetCursor (AvnStandardCursorType cursorType, void** ptr)
virtual HRESULT GetCursor (AvnStandardCursorType cursorType, IAvnCursor** retOut)
{
NSCursor * cursor;
switch (cursorType) {
case CursorArrow:
case CursorAppStarting:
case CursorWait:
cursor = [NSCursor arrowCursor];
break;
case CursorTopLeftCorner:
case CursorTopRightCorner:
case CursorBottomLeftCorner :
case CursorBottomRightCorner:
case CursorCross:
case CursorSizeAll:
cursor = [NSCursor crosshairCursor];
break;
case CursorTopSide:
case CursorUpArrow:
cursor = [NSCursor resizeUpCursor];
break;
case CursorBottomSize:
cursor = [NSCursor resizeDownCursor];
break;
case CursorDragCopy:
case CursorDragMove:
cursor = [NSCursor dragCopyCursor];
break;
case CursorDragLink:
cursor = [NSCursor dragLinkCursor];
break;
case CursorHand:
cursor = [NSCursor pointingHandCursor];
break;
case CursorHelp:
cursor = [NSCursor contextualMenuCursor];
break;
case CursorIbeam:
cursor = [NSCursor IBeamCursor];
break;
case CursorLeftSide:
cursor = [NSCursor resizeLeftCursor];
break;
case CursorRightSide:
cursor = [NSCursor resizeRightCursor];
break;
case CursorNo:
cursor = [NSCursor operationNotAllowedCursor];
break;
default:
cursor = [NSCursor operationNotAllowedCursor];
break;
}
*ptr = (__bridge void*)cursor;
*retOut = s_cursorMap[cursorType];
return S_OK;
}
};
extern IAvnCursor* CreateCursor()
extern IAvnCursorFactory* CreateCursorFactory()
{
return new Cursor();
return new CursorFactory();
}

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

@ -113,9 +113,9 @@ public:
return S_OK;
}
virtual HRESULT CreateCursor(IAvnCursor** ppv)
virtual HRESULT CreateCursorFactory(IAvnCursorFactory** ppv)
{
*ppv = ::CreateCursor();
*ppv = ::CreateCursorFactory();
return S_OK;
}
};

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

@ -1,15 +1,18 @@
#include "common.h"
#include "window.h"
#include "KeyTransform.h"
#include "cursor.h"
class WindowBaseImpl : public ComSingleObject<IAvnWindowBase, &IID_IAvnWindowBase>, public INSWindowHolder
{
private:
NSCursor* cursor;
public:
AvnView* View;
AvnWindow* Window;
ComPtr<IAvnWindowBaseEvents> BaseEvents;
AvnPoint lastPositionSet;
NSCursor* cursor;
WindowBaseImpl(IAvnWindowBaseEvents* events)
{
@ -190,24 +193,23 @@ public:
return S_OK;
}
virtual HRESULT SetCursor(void* ptr)
virtual HRESULT SetCursor(IAvnCursor* cursor)
{
cursor = (__bridge NSCursor*)ptr;
Cursor* avnCursor = dynamic_cast<Cursor*>(cursor);
this->cursor = avnCursor->GetNative();
UpdateCursor();
return S_OK;
}
virtual HRESULT UpdateCursor()
virtual void UpdateCursor()
{
[View resetCursorRects];
if (cursor != NULL)
if (cursor != nil)
{
auto rect = [Window frame];
[View addCursorRect:rect cursor:cursor];
// if ([View isMouseOver])
[cursor set];
[cursor set];
}
return S_OK;
}
protected:
@ -286,6 +288,8 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent
_area = [[NSTrackingArea alloc] initWithRect:rect options:options owner:self userInfo:nullptr];
[self addTrackingArea:_area];
_parent->UpdateCursor();
_parent->BaseEvents->Resized(AvnSize{newSize.width, newSize.height});
}

2
src/Avalonia.Native/AvaloniaNativePlatform.cs

@ -64,7 +64,7 @@ namespace Avalonia.Native
AvaloniaLocator.CurrentMutable
.Bind<IPlatformThreadingInterface>().ToConstant(new PlatformThreadingInterface(_factory.CreatePlatformThreadingInterface()))
.Bind<IStandardCursorFactory>().ToTransient<CursorFactoryStub>()
.Bind<IStandardCursorFactory>().ToConstant(new CursorFactory(_factory.CreateCursorFactory()))
.Bind<IPlatformIconLoader>().ToSingleton<IconLoader>()
.Bind<IKeyboardDevice>().ToConstant(KeyboardDevice)
.Bind<IMouseDevice>().ToConstant(MouseDevice)

25
src/Avalonia.Native/Cursor.cs

@ -5,31 +5,38 @@ using Avalonia.Native.Interop;
namespace Avalonia.Native
{
class Cursor : IPlatformHandle
class AvaloniaNativeCursor : IPlatformHandle, IDisposable
{
public IntPtr Handle { get; }
public IAvnCursor Cursor { get; private set; }
public IntPtr Handle => IntPtr.Zero;
public string HandleDescriptor => "NSCursor";
public string HandleDescriptor => "<none>";
public Cursor(IntPtr handle)
public AvaloniaNativeCursor(IAvnCursor cursor)
{
Handle = handle;
Cursor = cursor;
}
public void Dispose()
{
Cursor.Dispose();
Cursor = null;
}
}
class CursorFactory : IStandardCursorFactory
{
IAvnCursor _native;
IAvnCursorFactory _native;
public CursorFactory(IAvnCursor native)
public CursorFactory(IAvnCursorFactory native)
{
_native = native;
}
public IPlatformHandle GetCursor(StandardCursorType cursorType)
{
var handle = _native.GetCursor((AvnStandardCursorType)cursorType);
return new Cursor( handle );
var cursor = _native.GetCursor((AvnStandardCursorType)cursorType);
return new AvaloniaNativeCursor( cursor );
}
}
}

4
src/Avalonia.Native/WindowImplBase.cs

@ -312,7 +312,9 @@ namespace Avalonia.Native
public void SetCursor(IPlatformHandle cursor)
{
_native.Cursor = (cursor ?? _cursorFactory.GetCursor(StandardCursorType.Arrow)).Handle;
var newCursor = cursor as AvaloniaNativeCursor;
newCursor = newCursor ?? (_cursorFactory.GetCursor(StandardCursorType.Arrow) as AvaloniaNativeCursor);
_native.Cursor = newCursor.Cursor;
}
public void BeginResizeDrag(WindowEdge edge)

13
src/headers/avalonia-native.h

@ -1,6 +1,7 @@
#include "com.h"
#include "key.h"
#define AVNCOM(name, id) COMINTERFACE(name, 2e2cda0a, 9ae5, 4f1b, 8e, 20, 08, 1a, 04, 27, 9f, id)
struct IAvnWindowEvents;
@ -13,6 +14,7 @@ struct IAvnSystemDialogs;
struct IAvnScreens;
struct IAvnClipboard;
struct IAvnCursor;
struct IAvnCursorFactory;
struct AvnSize
{
@ -135,7 +137,7 @@ public:
virtual HRESULT CreateSystemDialogs (IAvnSystemDialogs** ppv) = 0;
virtual HRESULT CreateScreens (IAvnScreens** ppv) = 0;
virtual HRESULT CreateClipboard(IAvnClipboard** ppv) = 0;
virtual HRESULT CreateCursor(IAvnCursor** ppv) = 0;
virtual HRESULT CreateCursorFactory(IAvnCursorFactory** ppv) = 0;
};
AVNCOM(IAvnWindowBase, 02) : virtual IUnknown
@ -156,7 +158,7 @@ AVNCOM(IAvnWindowBase, 02) : virtual IUnknown
virtual HRESULT PointToScreen (AvnPoint point, AvnPoint*ret) = 0;
virtual HRESULT ThreadSafeSetSwRenderedFrame(AvnFramebuffer* fb, IUnknown* dispose) = 0;
virtual HRESULT SetTopMost (bool value) = 0;
virtual HRESULT SetCursor(void* ptr) = 0;
virtual HRESULT SetCursor(IAvnCursor* cursor) = 0;
};
AVNCOM(IAvnPopup, 03) : virtual IAvnWindowBase
@ -272,7 +274,12 @@ AVNCOM(IAvnClipboard, 0f) : virtual IUnknown
AVNCOM(IAvnCursor, 10) : virtual IUnknown
{
virtual HRESULT GetCursor (AvnStandardCursorType cursorType, void** retOut) = 0;
};
AVNCOM(IAvnCursorFactory, 11) : virtual IUnknown
{
virtual HRESULT GetCursor (AvnStandardCursorType cursorType, IAvnCursor** retOut) = 0;
};
extern "C" IAvaloniaNativeFactory* CreateAvaloniaNative();

Loading…
Cancel
Save