Browse Source

Refactoring SetCursor impl

ElBuda 7 years ago
parent
commit
a5f857874b

+ 2 - 0
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 */,

+ 1 - 1
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 - 0
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 */

+ 45 - 56
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();
 }

+ 2 - 2
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;
     }
 };

+ 12 - 8
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});
 }
 

+ 1 - 1
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)

+ 16 - 9
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 );
         }
     }
 }

+ 3 - 1
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)

+ 10 - 3
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();