Преглед изворни кода

First impl for setting mouse cursor

ElBuda пре 7 година
родитељ
комит
39ea679ec3

+ 4 - 0
src/Avalonia.Native.OSX/Avalonia.Native.OSX.xcodeproj/project.pbxproj

@@ -10,6 +10,7 @@
 		37A517B32159597E00FBA241 /* Screens.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37A517B22159597E00FBA241 /* Screens.mm */; };
 		37C09D8821580FE4006A6758 /* SystemDialogs.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37C09D8721580FE4006A6758 /* SystemDialogs.mm */; };
 		37E2330F21583241000CB7E2 /* KeyTransform.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37E2330E21583241000CB7E2 /* KeyTransform.mm */; };
+		5B21A982216530F500CEE36E /* cursor.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5B21A981216530F500CEE36E /* cursor.mm */; };
 		5B8BD94F215BFEA6005ED2A7 /* clipboard.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5B8BD94E215BFEA6005ED2A7 /* clipboard.mm */; };
 		AB00E4F72147CA920032A60A /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB00E4F62147CA920032A60A /* main.mm */; };
 		AB661C1E2148230F00291242 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB661C1D2148230F00291242 /* AppKit.framework */; };
@@ -24,6 +25,7 @@
 		37C09D8721580FE4006A6758 /* SystemDialogs.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = SystemDialogs.mm; sourceTree = "<group>"; };
 		37C09D8A21581EF2006A6758 /* window.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = window.h; sourceTree = "<group>"; };
 		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>"; };
 		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; };
@@ -56,6 +58,7 @@
 		AB7A61E62147C814003C5833 = {
 			isa = PBXGroup;
 			children = (
+				5B21A981216530F500CEE36E /* cursor.mm */,
 				5B8BD94E215BFEA6005ED2A7 /* clipboard.mm */,
 				379A4506214D0F6500CC143D /* headers */,
 				AB8F7D6A21482D7F0057DBA5 /* platformthreading.mm */,
@@ -148,6 +151,7 @@
 			buildActionMask = 2147483647;
 			files = (
 				5B8BD94F215BFEA6005ED2A7 /* clipboard.mm in Sources */,
+				5B21A982216530F500CEE36E /* cursor.mm in Sources */,
 				AB8F7D6B21482D7F0057DBA5 /* platformthreading.mm in Sources */,
 				37E2330F21583241000CB7E2 /* KeyTransform.mm in Sources */,
 				37A517B32159597E00FBA241 /* Screens.mm in Sources */,

+ 1 - 0
src/Avalonia.Native.OSX/common.h

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

+ 67 - 0
src/Avalonia.Native.OSX/cursor.mm

@@ -0,0 +1,67 @@
+#include "common.h"
+
+class Cursor : public ComSingleObject<IAvnCursor, &IID_IAvnCursor>
+{
+public:
+    virtual HRESULT GetCursor (AvnStandardCursorType cursorType, void** ptr)
+    {
+        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;
+        return S_OK;
+    }
+};
+
+extern IAvnCursor* CreateCursor()
+{
+    return new Cursor();
+}

+ 6 - 0
src/Avalonia.Native.OSX/main.mm

@@ -112,6 +112,12 @@ public:
         *ppv = ::CreateClipboard ();
         return S_OK;
     }
+
+    virtual HRESULT CreateCursor(IAvnCursor** ppv)
+    {
+        *ppv = ::CreateCursor();
+        return S_OK;
+    }
 };
 
 extern "C" IAvaloniaNativeFactory* CreateAvaloniaNative()

+ 22 - 0
src/Avalonia.Native.OSX/window.mm

@@ -9,6 +9,8 @@ public:
     AvnWindow* Window;
     ComPtr<IAvnWindowBaseEvents> BaseEvents;
     AvnPoint lastPositionSet;
+    NSCursor* cursor;
+    
     WindowBaseImpl(IAvnWindowBaseEvents* events)
     {
         BaseEvents = events;
@@ -188,6 +190,26 @@ public:
         return S_OK;
     }
     
+    virtual HRESULT SetCursor(void* ptr)
+    {
+        cursor = (__bridge NSCursor*)ptr;
+        UpdateCursor();
+        return S_OK;
+    }
+
+    virtual HRESULT UpdateCursor()
+    {
+        [View resetCursorRects];
+        if (cursor != NULL)
+        {
+             auto rect = [Window frame];
+             [View addCursorRect:rect cursor:cursor];
+//           if ([View isMouseOver])
+                 [cursor set];
+        }
+        return S_OK;
+    }
+
 protected:
     virtual NSWindowStyleMask GetStyle()
     {

+ 1 - 2
src/Avalonia.Native/AvaloniaNativePlatform.cs

@@ -63,9 +63,8 @@ namespace Avalonia.Native
             _factory.Initialize();
 
             AvaloniaLocator.CurrentMutable
-                .Bind<IStandardCursorFactory>().ToTransient<CursorFactoryStub>()
+                .Bind<IStandardCursorFactory>().ToConstant(new CursorFactory(_factory.CreateCursor()))
                 .Bind<IPlatformIconLoader>().ToSingleton<IconLoader>()
-
                 .Bind<IKeyboardDevice>().ToConstant(KeyboardDevice)
                 .Bind<IMouseDevice>().ToConstant(MouseDevice)
                 .Bind<IPlatformSettings>().ToConstant(this)

+ 0 - 0
src/Avalonia.Native/Stubs.cs → src/Avalonia.Native/ClipboardImpl.cs


+ 18 - 4
src/Avalonia.Native/Cursor.cs

@@ -1,21 +1,35 @@
 using System;
 using Avalonia.Input;
 using Avalonia.Platform;
+using Avalonia.Native.Interop;
 
 namespace Avalonia.Native
 {
     class Cursor : IPlatformHandle
     {
-        public IntPtr Handle => IntPtr.Zero;
+        public IntPtr Handle { get; }
 
-        public string HandleDescriptor => "STUB";
+        public string HandleDescriptor => "NSCursor";
+
+        public Cursor(IntPtr handle)
+        {
+            Handle = handle;
+        }
     }
 
-    class CursorFactoryStub : IStandardCursorFactory
+    class CursorFactory : IStandardCursorFactory
     {
+        IAvnCursor _native;
+
+        public CursorFactory(IAvnCursor native)
+        {
+            _native = native;
+        }
+
         public IPlatformHandle GetCursor(StandardCursorType cursorType)
         {
-            return new Cursor();
+            var handle = _native.GetCursor((AvnStandardCursorType)cursorType);
+            return new Cursor( handle );
         }
     }
 }

+ 3 - 0
src/Avalonia.Native/WindowImplBase.cs

@@ -19,6 +19,7 @@ namespace Avalonia.Native
         private bool _deferredRendering = true;
         private readonly IMouseDevice _mouse;
         private readonly IKeyboardDevice _keyboard;
+        private readonly IStandardCursorFactory _cursorFactory;
         private Size _savedLogicalSize;
         private Size _lastRenderedLogicalSize;
         private double _savedScaling;
@@ -27,6 +28,7 @@ namespace Avalonia.Native
         {
             _keyboard = AvaloniaLocator.Current.GetService<IKeyboardDevice>();
             _mouse = AvaloniaLocator.Current.GetService<IMouseDevice>();
+            _cursorFactory = AvaloniaLocator.Current.GetService<IStandardCursorFactory>();
         }
 
         protected void Init(IAvnWindowBase window, IAvnScreens screens)
@@ -310,6 +312,7 @@ namespace Avalonia.Native
 
         public void SetCursor(IPlatformHandle cursor)
         {
+            _native.Cursor = (cursor ?? _cursorFactory.GetCursor(StandardCursorType.Arrow)).Handle;
         }
 
         public void BeginResizeDrag(WindowEdge edge)

+ 35 - 0
src/headers/avalonia-native.h

@@ -12,6 +12,7 @@ struct IAvnSystemDialogEvents;
 struct IAvnSystemDialogs;
 struct IAvnScreens;
 struct IAvnClipboard;
+struct IAvnCursor;
 
 struct AvnSize
 {
@@ -96,6 +97,33 @@ enum AvnWindowState
     Maximized,
 };
 
+enum AvnStandardCursorType
+{
+    CursorArrow,
+    CursorIbeam,
+    CursorWait,
+    CursorCross,
+    CursorUpArrow,
+    CursorSizeWestEast,
+    CursorSizeNorthSouth,
+    CursorSizeAll,
+    CursorNo,
+    CursorHand,
+    CursorAppStarting,
+    CursorHelp,
+    CursorTopSide,
+    CursorBottomSize,
+    CursorLeftSide,
+    CursorRightSide,
+    CursorTopLeftCorner,
+    CursorTopRightCorner,
+    CursorBottomLeftCorner,
+    CursorBottomRightCorner,
+    CursorDragMove,
+    CursorDragCopy,
+    CursorDragLink,
+};
+
 AVNCOM(IAvaloniaNativeFactory, 01) : virtual IUnknown
 {
 public:
@@ -107,6 +135,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;
 };
 
 AVNCOM(IAvnWindowBase, 02) : virtual IUnknown
@@ -127,6 +156,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;
 };
 
 AVNCOM(IAvnPopup, 03) : virtual IAvnWindowBase
@@ -240,4 +270,9 @@ AVNCOM(IAvnClipboard, 0f) : virtual IUnknown
     virtual HRESULT Clear() = 0;
 };
 
+AVNCOM(IAvnCursor, 10) : virtual IUnknown
+{
+    virtual HRESULT GetCursor (AvnStandardCursorType cursorType, void** retOut) = 0;
+};
+
 extern "C" IAvaloniaNativeFactory* CreateAvaloniaNative();