Macでもファイルドロップを実装中。

This commit is contained in:
Kirurobo
2020-11-29 15:20:44 +09:00
parent 656333e5e7
commit 224080b280
29 changed files with 329 additions and 66 deletions

View File

@@ -17,7 +17,7 @@
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>0.4.1</string>
<string>0.5.9</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>MacOSX</string>
@@ -41,7 +41,7 @@
<key>DTXcodeBuild</key>
<string>12B45b</string>
<key>LSMinimumSystemVersion</key>
<string>10.11</string>
<string>10.13</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2019-2020 kirurobo. All rights reserved.</string>
</dict>

View File

@@ -10,163 +10,163 @@
<dict>
<key>cdhash</key>
<data>
KGMjRv+hR501l/7QZYoM2T13WZE=
z1kgPsh1fxqmbYe2oZybTgbGaCo=
</data>
<key>requirement</key>
<string>identifier "com.apple.dt.runtime.swiftAppKit" and anchor apple generic and certificate leaf[subject.CN] = "Apple Development: Ryota Sakamoto (Q8T2P8EN2T)" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */</string>
<string>identifier "com.apple.dt.runtime.swiftAppKit" and anchor apple generic and certificate leaf[subject.CN] = "Apple Distribution: Ryota Sakamoto (F4K53USRZ7)" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */</string>
</dict>
<key>Frameworks/libswiftCloudKit.dylib</key>
<dict>
<key>cdhash</key>
<data>
gmHZ6EtjZXwLmOROWLvNh5atYzU=
zSx0cRAmQ6hl7DnutSkAvDe6Jdk=
</data>
<key>requirement</key>
<string>identifier "com.apple.dt.runtime.swiftCloudKit" and anchor apple generic and certificate leaf[subject.CN] = "Apple Development: Ryota Sakamoto (Q8T2P8EN2T)" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */</string>
<string>identifier "com.apple.dt.runtime.swiftCloudKit" and anchor apple generic and certificate leaf[subject.CN] = "Apple Distribution: Ryota Sakamoto (F4K53USRZ7)" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */</string>
</dict>
<key>Frameworks/libswiftContacts.dylib</key>
<dict>
<key>cdhash</key>
<data>
zvewrNbJbl2qZ9pt9xS1I5WzYos=
t7P9TBa/MunuopDZe5EKoniu05s=
</data>
<key>requirement</key>
<string>identifier "com.apple.dt.runtime.swiftContacts" and anchor apple generic and certificate leaf[subject.CN] = "Apple Development: Ryota Sakamoto (Q8T2P8EN2T)" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */</string>
<string>identifier "com.apple.dt.runtime.swiftContacts" and anchor apple generic and certificate leaf[subject.CN] = "Apple Distribution: Ryota Sakamoto (F4K53USRZ7)" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */</string>
</dict>
<key>Frameworks/libswiftCore.dylib</key>
<dict>
<key>cdhash</key>
<data>
TAxXkG2x/OYQDYVLLEu/36Il+QQ=
zS5w50y15TLh1dtDp/SlX3R7T0Q=
</data>
<key>requirement</key>
<string>identifier "com.apple.dt.runtime.swiftCore" and anchor apple generic and certificate leaf[subject.CN] = "Apple Development: Ryota Sakamoto (Q8T2P8EN2T)" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */</string>
<string>identifier "com.apple.dt.runtime.swiftCore" and anchor apple generic and certificate leaf[subject.CN] = "Apple Distribution: Ryota Sakamoto (F4K53USRZ7)" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */</string>
</dict>
<key>Frameworks/libswiftCoreData.dylib</key>
<dict>
<key>cdhash</key>
<data>
ep9f6hG7E7oLGagK4e3IOQ9ssKE=
YJNgZf7vKkJhERTz7R6I3sKf6TA=
</data>
<key>requirement</key>
<string>identifier "com.apple.dt.runtime.swiftCoreData" and anchor apple generic and certificate leaf[subject.CN] = "Apple Development: Ryota Sakamoto (Q8T2P8EN2T)" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */</string>
<string>identifier "com.apple.dt.runtime.swiftCoreData" and anchor apple generic and certificate leaf[subject.CN] = "Apple Distribution: Ryota Sakamoto (F4K53USRZ7)" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */</string>
</dict>
<key>Frameworks/libswiftCoreFoundation.dylib</key>
<dict>
<key>cdhash</key>
<data>
9ffdtnIZyt1p6M1vYM03DnvrD5s=
CxiAnYDk4TJDYG3aH81xw6C7J/Q=
</data>
<key>requirement</key>
<string>identifier "com.apple.dt.runtime.swiftCoreFoundation" and anchor apple generic and certificate leaf[subject.CN] = "Apple Development: Ryota Sakamoto (Q8T2P8EN2T)" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */</string>
<string>identifier "com.apple.dt.runtime.swiftCoreFoundation" and anchor apple generic and certificate leaf[subject.CN] = "Apple Distribution: Ryota Sakamoto (F4K53USRZ7)" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */</string>
</dict>
<key>Frameworks/libswiftCoreGraphics.dylib</key>
<dict>
<key>cdhash</key>
<data>
8twBlZE/TQfExiECCt8zfAXElVU=
ivoKaRD47pKN+mZKjBI66Zpra1o=
</data>
<key>requirement</key>
<string>identifier "com.apple.dt.runtime.swiftCoreGraphics" and anchor apple generic and certificate leaf[subject.CN] = "Apple Development: Ryota Sakamoto (Q8T2P8EN2T)" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */</string>
<string>identifier "com.apple.dt.runtime.swiftCoreGraphics" and anchor apple generic and certificate leaf[subject.CN] = "Apple Distribution: Ryota Sakamoto (F4K53USRZ7)" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */</string>
</dict>
<key>Frameworks/libswiftCoreImage.dylib</key>
<dict>
<key>cdhash</key>
<data>
fi9JRb1jBgs4Dor7eLwyYiyl48Y=
W/WXSGG5ecdhoJY82D6jTRvcoss=
</data>
<key>requirement</key>
<string>identifier "com.apple.dt.runtime.swiftCoreImage" and anchor apple generic and certificate leaf[subject.CN] = "Apple Development: Ryota Sakamoto (Q8T2P8EN2T)" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */</string>
<string>identifier "com.apple.dt.runtime.swiftCoreImage" and anchor apple generic and certificate leaf[subject.CN] = "Apple Distribution: Ryota Sakamoto (F4K53USRZ7)" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */</string>
</dict>
<key>Frameworks/libswiftCoreLocation.dylib</key>
<dict>
<key>cdhash</key>
<data>
LS0s9RQWGhqotiG8hBJ7hQR77Qw=
TUgUbXwn1C/l5zJxpXREDZLy/0c=
</data>
<key>requirement</key>
<string>identifier "com.apple.dt.runtime.swiftCoreLocation" and anchor apple generic and certificate leaf[subject.CN] = "Apple Development: Ryota Sakamoto (Q8T2P8EN2T)" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */</string>
<string>identifier "com.apple.dt.runtime.swiftCoreLocation" and anchor apple generic and certificate leaf[subject.CN] = "Apple Distribution: Ryota Sakamoto (F4K53USRZ7)" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */</string>
</dict>
<key>Frameworks/libswiftDarwin.dylib</key>
<dict>
<key>cdhash</key>
<data>
lQvhZzT9ZvhXbi5i2sFaPrbwGmw=
DpqM8OpCYmbaU1Ub1cPeyN/iczI=
</data>
<key>requirement</key>
<string>identifier "com.apple.dt.runtime.swiftDarwin" and anchor apple generic and certificate leaf[subject.CN] = "Apple Development: Ryota Sakamoto (Q8T2P8EN2T)" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */</string>
<string>identifier "com.apple.dt.runtime.swiftDarwin" and anchor apple generic and certificate leaf[subject.CN] = "Apple Distribution: Ryota Sakamoto (F4K53USRZ7)" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */</string>
</dict>
<key>Frameworks/libswiftDispatch.dylib</key>
<dict>
<key>cdhash</key>
<data>
kcg1+rZZQ0bDKZG9kKfkpUeZ+5E=
hRX2UQAGeWKK6nhGk8NoKyA+lbw=
</data>
<key>requirement</key>
<string>identifier "com.apple.dt.runtime.swiftDispatch" and anchor apple generic and certificate leaf[subject.CN] = "Apple Development: Ryota Sakamoto (Q8T2P8EN2T)" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */</string>
<string>identifier "com.apple.dt.runtime.swiftDispatch" and anchor apple generic and certificate leaf[subject.CN] = "Apple Distribution: Ryota Sakamoto (F4K53USRZ7)" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */</string>
</dict>
<key>Frameworks/libswiftFoundation.dylib</key>
<dict>
<key>cdhash</key>
<data>
YiQMYWxpiAvMWElak4gTqO04XE0=
27JxDGDpym+M1KwaPBTA3tO6400=
</data>
<key>requirement</key>
<string>identifier "com.apple.dt.runtime.swiftFoundation" and anchor apple generic and certificate leaf[subject.CN] = "Apple Development: Ryota Sakamoto (Q8T2P8EN2T)" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */</string>
<string>identifier "com.apple.dt.runtime.swiftFoundation" and anchor apple generic and certificate leaf[subject.CN] = "Apple Distribution: Ryota Sakamoto (F4K53USRZ7)" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */</string>
</dict>
<key>Frameworks/libswiftIOKit.dylib</key>
<dict>
<key>cdhash</key>
<data>
L+UE40tgvH/6pNH9wIgQarUthEs=
QSqC5z8PNaPtC4RC+D9dIrw9ZGk=
</data>
<key>requirement</key>
<string>identifier "com.apple.dt.runtime.swiftIOKit" and anchor apple generic and certificate leaf[subject.CN] = "Apple Development: Ryota Sakamoto (Q8T2P8EN2T)" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */</string>
<string>identifier "com.apple.dt.runtime.swiftIOKit" and anchor apple generic and certificate leaf[subject.CN] = "Apple Distribution: Ryota Sakamoto (F4K53USRZ7)" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */</string>
</dict>
<key>Frameworks/libswiftMetal.dylib</key>
<dict>
<key>cdhash</key>
<data>
j4iP0inzKdBC0tM92cLokaKYyLQ=
0c6kYqnoyBCZyTqNOaI00KJE1CU=
</data>
<key>requirement</key>
<string>identifier "com.apple.dt.runtime.swiftMetal" and anchor apple generic and certificate leaf[subject.CN] = "Apple Development: Ryota Sakamoto (Q8T2P8EN2T)" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */</string>
<string>identifier "com.apple.dt.runtime.swiftMetal" and anchor apple generic and certificate leaf[subject.CN] = "Apple Distribution: Ryota Sakamoto (F4K53USRZ7)" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */</string>
</dict>
<key>Frameworks/libswiftObjectiveC.dylib</key>
<dict>
<key>cdhash</key>
<data>
omx6TE1Aoduv6WHB976OPc3zwN4=
HHe6V8uwbtoB3IdOeaXYZ9YnePQ=
</data>
<key>requirement</key>
<string>identifier "com.apple.dt.runtime.swiftObjectiveC" and anchor apple generic and certificate leaf[subject.CN] = "Apple Development: Ryota Sakamoto (Q8T2P8EN2T)" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */</string>
<string>identifier "com.apple.dt.runtime.swiftObjectiveC" and anchor apple generic and certificate leaf[subject.CN] = "Apple Distribution: Ryota Sakamoto (F4K53USRZ7)" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */</string>
</dict>
<key>Frameworks/libswiftQuartzCore.dylib</key>
<dict>
<key>cdhash</key>
<data>
Mya4a7NerMbQb6AuvcEp1Sn1XQY=
ml9+u5Rp4bklk4QDRcdz/VDpULM=
</data>
<key>requirement</key>
<string>identifier "com.apple.dt.runtime.swiftQuartzCore" and anchor apple generic and certificate leaf[subject.CN] = "Apple Development: Ryota Sakamoto (Q8T2P8EN2T)" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */</string>
<string>identifier "com.apple.dt.runtime.swiftQuartzCore" and anchor apple generic and certificate leaf[subject.CN] = "Apple Distribution: Ryota Sakamoto (F4K53USRZ7)" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */</string>
</dict>
<key>Frameworks/libswiftXPC.dylib</key>
<dict>
<key>cdhash</key>
<data>
Iujfz/FQANSpBno4nXSU9fPupIc=
0l/8R9V8ly99s5zfe6D1Lmt52HI=
</data>
<key>requirement</key>
<string>identifier "com.apple.dt.runtime.swiftXPC" and anchor apple generic and certificate leaf[subject.CN] = "Apple Development: Ryota Sakamoto (Q8T2P8EN2T)" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */</string>
<string>identifier "com.apple.dt.runtime.swiftXPC" and anchor apple generic and certificate leaf[subject.CN] = "Apple Distribution: Ryota Sakamoto (F4K53USRZ7)" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */</string>
</dict>
<key>Frameworks/libswiftos.dylib</key>
<dict>
<key>cdhash</key>
<data>
kw/hpB91m6sNovPmNgqFzT3Axpw=
w9Zro23XHNs5K4HOFrioj9q1gMU=
</data>
<key>requirement</key>
<string>identifier "com.apple.dt.runtime.swiftos" and anchor apple generic and certificate leaf[subject.CN] = "Apple Development: Ryota Sakamoto (Q8T2P8EN2T)" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */</string>
<string>identifier "com.apple.dt.runtime.swiftos" and anchor apple generic and certificate leaf[subject.CN] = "Apple Distribution: Ryota Sakamoto (F4K53USRZ7)" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */</string>
</dict>
</dict>
<key>rules</key>

View File

@@ -1,4 +1,4 @@
/**
/*
* UniWinCore.cs
*
* Author: Kirurobo http://twitter.com/kirurobo
@@ -6,7 +6,7 @@
*/
using System;
using System.Reflection;
using System.Linq;
using System.Runtime.InteropServices;
using UnityEngine;
#if UNITY_EDITOR
@@ -28,6 +28,7 @@ public class UniWinCore : IDisposable
ColorKey = 2,
}
#region Native functions
protected class LibUniWinC
{
[DllImport("LibUniWinC")]
@@ -83,15 +84,27 @@ public class UniWinCore : IDisposable
[DllImport("LibUniWinC")]
public static extern bool GetSize(out float x, out float y);
[UnmanagedFunctionPointer((CallingConvention.Cdecl))]
public delegate void StringCallback([MarshalAs(UnmanagedType.LPWStr)] string returnString);
[DllImport("LibUniWinC")]
public static extern Int32 GetCurrentMonitor();
public static extern bool RegisterFileDropCallback([MarshalAs(UnmanagedType.FunctionPtr)] StringCallback callback);
[DllImport("LibUniWinC")]
public static extern Int32 GetMonitorCount();
public static extern bool UnregisterFileDropCallback();
[DllImport("LibUniWinC")]
public static extern bool GetMonitorRectangle(Int32 index, out float x, out float y, out float width, out float height);
public static extern bool SetAllowDrop(bool enabled);
[DllImport("LibUniWinC")]
public static extern int GetCurrentMonitor();
[DllImport("LibUniWinC")]
public static extern int GetMonitorCount();
[DllImport("LibUniWinC")]
public static extern bool GetMonitorRectangle(int index, out float x, out float y, out float width, out float height);
[DllImport("LibUniWinC")]
public static extern void SetCursorPosition(float x, float y);
@@ -100,11 +113,12 @@ public class UniWinCore : IDisposable
public static extern bool GetCursorPosition(out float x, out float y);
[DllImport("LibUniWinC")]
public static extern void SetTransparentType(Int32 type);
public static extern void SetTransparentType(int type);
[DllImport("LibUniWinC")]
public static extern void SetKeyColor(UInt32 colorref);
public static extern void SetKeyColor(uint colorref);
}
#endregion
#if UNITY_EDITOR
@@ -157,7 +171,10 @@ public class UniWinCore : IDisposable
private Color32 ChromakeyColor = new Color32(1, 0, 1, 0);
public delegate void FileDropCallback(string[] files);
#region Constructor or destructor
/// <summary>
/// ウィンドウ制御のコンストラクタ
/// </summary>
@@ -181,7 +198,12 @@ public class UniWinCore : IDisposable
{
// 最後にウィンドウ状態を戻すとそれが目についてしまうので、現状必ずしも戻さないようコメントアウト
//DetachWindow();
LibUniWinC.UnregisterFileDropCallback();
}
#endregion
#region Find, attach or detach
/// <summary>
/// ウィンドウ状態を最初に戻して操作対象から解除
@@ -208,6 +230,9 @@ public class UniWinCore : IDisposable
#else
LibUniWinC.AttachMyWindow();
#endif
// Add file drop handler
LibUniWinC.RegisterFileDropCallback(_fileDroppedCallback);
IsActive = LibUniWinC.IsActive();
return IsActive;
}
@@ -224,6 +249,10 @@ public class UniWinCore : IDisposable
return IsActive;
}
#endregion
#region About window status
/// <summary>
/// 透過を設定/解除
/// </summary>
@@ -318,7 +347,31 @@ public class UniWinCore : IDisposable
LibUniWinC.GetSize(out size.x, out size.y);
return size;
}
#endregion
#region About file dropping
public void SetAllowDrop(bool enabled)
{
LibUniWinC.SetAllowDrop(enabled);
}
private void _fileDroppedCallback([MarshalAs(UnmanagedType.LPWStr)] string paths)
{
Debug.Log(paths);
char[] delimiters = {'\n', '\r', '\t', '\0'};
string[] files = paths.Split(delimiters).Where(s => s != "").ToArray();
if (files.Length > 0)
{
//OnFileDropped?.Invoke(files);
}
}
public event FileDropCallback OnFileDropped;
#endregion
#region About mouse cursor
/// <summary>
/// Set the mouse pointer position.
/// </summary>
@@ -339,6 +392,14 @@ public class UniWinCore : IDisposable
return pos;
}
// Not implemented
public static bool GetCursorVisible()
{
return true;
}
#endregion
#region for Windows only
/// <summary>
/// 透過方法を指定Windowsのみ対応
/// </summary>
@@ -358,7 +419,9 @@ public class UniWinCore : IDisposable
LibUniWinC.SetKeyColor((UInt32)(color.b * 0x10000 + color.g * 0x100 + color.r));
ChromakeyColor = color;
}
#endregion
#region About monitors
/// <summary>
/// Get the monitor index where the window is located
/// </summary>
@@ -417,11 +480,6 @@ public class UniWinCore : IDisposable
}
Debug.Log(message);
}
#endregion
// Not implemented
public static bool GetCursorVisible()
{
return true;
}
}

View File

@@ -94,6 +94,17 @@ namespace Kirurobo
[SerializeField, BoolProperty, Tooltip("Experimental...")]
private bool _isZoomed = false;
/// <summary>
/// Is this window minimized
/// </summary>
public bool isFileDropEnabled
{
get { return _isFileDropEnabled; }
set { SetAllowDrop(value); }
}
[SerializeField, BoolProperty, Tooltip("Experimental...")]
private bool _isFileDropEnabled = false;
/// <summary>
/// クリックスルー自動判定を行うか
/// 行なわない場合は isClickThrough を自分で変更可
@@ -217,8 +228,12 @@ namespace Kirurobo
/// ウィンドウ状態が変化したときに発生するイベント
/// </summary>
public event OnStateChangedDelegate OnStateChanged;
public delegate void OnStateChangedDelegate();
public event OnFileDroppedDelegate OnFileDropped;
public delegate void OnFileDroppedDelegate(string[] files);
// Use this for initialization
@@ -263,6 +278,7 @@ namespace Kirurobo
// ウィンドウ制御用のインスタンス作成
uniWinCore = new UniWinCore();
uniWinCore.OnFileDropped += (files) => { OnFileDropped?.Invoke(files); };
}
void Start()
@@ -634,6 +650,15 @@ namespace Kirurobo
StateChangedEvent();
}
private void SetAllowDrop(bool enabled)
{
if (uniWinCore == null) return;
uniWinCore.SetAllowDrop(enabled);
_isFileDropEnabled = enabled;
StateChangedEvent();
}
/// <summary>
/// 接続されているモニタ数を取得
/// </summary>

View File

@@ -1,4 +1,4 @@
/**
/*
* UniWindowDragMove.cs
*
* Author: Kirurobo http://twitter.com/kirurobo

View File

@@ -38,6 +38,7 @@ GraphicsSettings:
- {fileID: 10783, guid: 0000000000000000f000000000000000, type: 0}
- {fileID: 16000, guid: 0000000000000000f000000000000000, type: 0}
- {fileID: 17000, guid: 0000000000000000f000000000000000, type: 0}
- {fileID: 16001, guid: 0000000000000000f000000000000000, type: 0}
m_PreloadedShaders: []
m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000,
type: 0}

View File

@@ -7,12 +7,14 @@
objects = {
/* Begin PBXBuildFile section */
731C6C6E25724025002E9709 /* OverlayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 731C6C6D25724025002E9709 /* OverlayView.swift */; };
73575EF522BE0AB300E9F019 /* LibUniWinC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 73575EF422BE0AB300E9F019 /* LibUniWinC.swift */; };
73575EF922BE18B200E9F019 /* LibUniWinC.mm in Sources */ = {isa = PBXBuildFile; fileRef = 73575EF822BE18B200E9F019 /* LibUniWinC.mm */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
7306572424F1F87900FAB8BC /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
731C6C6D25724025002E9709 /* OverlayView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OverlayView.swift; sourceTree = "<group>"; };
73575EF422BE0AB300E9F019 /* LibUniWinC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LibUniWinC.swift; sourceTree = "<group>"; };
73575EF822BE18B200E9F019 /* LibUniWinC.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = LibUniWinC.mm; sourceTree = "<group>"; };
73DFCB7722B8ED3300DA41F2 /* LibUniWinC.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = LibUniWinC.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -53,6 +55,7 @@
73575EF422BE0AB300E9F019 /* LibUniWinC.swift */,
73575EF822BE18B200E9F019 /* LibUniWinC.mm */,
7306572424F1F87900FAB8BC /* README.md */,
731C6C6D25724025002E9709 /* OverlayView.swift */,
);
path = LibUniWinC;
sourceTree = "<group>";
@@ -146,6 +149,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
731C6C6E25724025002E9709 /* OverlayView.swift in Sources */,
73575EF922BE18B200E9F019 /* LibUniWinC.mm in Sources */,
73575EF522BE0AB300E9F019 /* LibUniWinC.swift in Sources */,
);
@@ -285,8 +289,8 @@
"@executable_path/../Frameworks",
"@loader_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 10.11;
MARKETING_VERSION = 0.4.1;
MACOSX_DEPLOYMENT_TARGET = 10.13;
MARKETING_VERSION = 0.5.9;
PRODUCT_BUNDLE_IDENTIFIER = com.kirurobo.libuniwinc;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
@@ -313,8 +317,8 @@
"@executable_path/../Frameworks",
"@loader_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 10.11;
MARKETING_VERSION = 0.4.1;
MACOSX_DEPLOYMENT_TARGET = 10.13;
MARKETING_VERSION = 0.5.9;
PRODUCT_BUNDLE_IDENTIFIER = com.kirurobo.libuniwinc;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;

View File

@@ -12,6 +12,10 @@
#import <Foundation/Foundation.h>
#import "LibUniWinC-Swift.h"
// Actually the argument type is wchar_t*
using StringCallback = void(* _Nonnull)(const void* _Nonnull);
UNIWINC_EXPORT BOOL IsActive() {
return [LibUniWinC isActive];
}
@@ -89,7 +93,7 @@ UNIWINC_EXPORT SInt32 GetCurrentMonitor() {
return [LibUniWinC getCurrentMonitor];
}
UNIWINC_EXPORT BOOL GetMonitorCount() {
UNIWINC_EXPORT SInt32 GetMonitorCount() {
return [LibUniWinC getMonitorCount];
}
@@ -97,6 +101,18 @@ UNIWINC_EXPORT BOOL GetMonitorRectangle(SInt32 monitorIndex, Float32* x, Float32
return [LibUniWinC getMonitorRectangleWithMonitorIndex:monitorIndex x:x y:y width:width height:height];
}
UNIWINC_EXPORT BOOL SetAllowDrop(BOOL enabled) {
return [LibUniWinC setAllowDropWithEnabled: enabled];
}
UNIWINC_EXPORT BOOL RegisterFileDropCallback(StringCallback callback) {
return [LibUniWinC registerFileDropCallbackWithCallback: callback];
}
UNIWINC_EXPORT BOOL UnregisterFileDropCallback() {
return [LibUniWinC unregisterFileDropCallback];
}
UNIWINC_EXPORT BOOL SetCursorPosition(Float32 x, Float32 y) {
return [LibUniWinC setCursorPositionWithX:x y:y];
}

View File

@@ -91,6 +91,9 @@ public class LibUniWinC : NSObject {
}
}
/// Callback function with wchar_t pointer
public typealias stringCallback = (@convention(c) (UnsafeRawPointer) -> Void)
// MARK: - Static variables
@@ -103,6 +106,11 @@ public class LibUniWinC : NSObject {
///
private static var orgWindowInfo: OriginalWindowInfo = OriginalWindowInfo()
/// Sub view to implement file dropping
private static var overlayView: OverlayView? = nil
public static var fileDropCallback: stringCallback? = nil
///
private static var primaryMonitorHeight: CGFloat = 0
@@ -150,6 +158,12 @@ public class LibUniWinC : NSObject {
//
orgWindowInfo.Restore(window: targetWindow!)
// Remove the subview
if (overlayView != nil) {
targetWindow?.contentView?.willRemoveSubview(overlayView!)
overlayView = nil
}
targetWindow = nil
}
@@ -173,7 +187,7 @@ public class LibUniWinC : NSObject {
}
private static func _updateScreenSize() -> Void {
// https://stackoverrun.com/ja/q/1746184
// Reference: https://stackoverrun.com/ja/q/1746184
primaryMonitorHeight = NSScreen.screens.map {$0.frame.origin.y + $0.frame.height}.max()!
//
@@ -203,7 +217,7 @@ public class LibUniWinC : NSObject {
}
///
private static func setup() -> Void {
private static func _setup() -> Void {
//
_updateScreenSize()
@@ -217,7 +231,6 @@ public class LibUniWinC : NSObject {
_updateScreenSize()
}
state.isReady = true
}
@@ -239,7 +252,7 @@ public class LibUniWinC : NSObject {
//
if (!state.isReady) {
setup()
_setup()
}
//
@@ -255,17 +268,24 @@ public class LibUniWinC : NSObject {
NotificationCenter.default.addObserver(
forName: NSWindow.didEnterFullScreenNotification,
object: nil,
queue: OperationQueue.main) { notification -> Void in
_reapplyWindowStyles()
queue: OperationQueue.main)
{
notification -> Void in _reapplyWindowStyles()
}
//
NotificationCenter.default.addObserver(
forName: NSWindow.didExitFullScreenNotification,
object: nil,
queue: OperationQueue.main) { notification -> Void in
_reapplyWindowStyles()
queue: OperationQueue.main)
{
notification -> Void in _reapplyWindowStyles()
}
// Add a subview to handle file dropping
overlayView = OverlayView(frame: window.frame)
window.contentView?.addSubview(overlayView!)
//overlayView?.fitToSuperView()
}
///
@@ -570,7 +590,23 @@ public class LibUniWinC : NSObject {
x.pointee = Float32(frame.minX)
y.pointee = Float32(frame.minY)
width.pointee = Float32(frame.width)
height.pointee = Float32(frame.height)
//height.pointee = Float32(frame.height)
height.pointee = Float32(fileDropCallback.debugDescription.count)
return true
}
@objc public static func setAllowDrop(enabled: Bool) -> Bool {
overlayView?.setEnabled(enabled: enabled)
return true
}
@objc public static func registerFileDropCallback(callback: @escaping stringCallback) -> Bool {
fileDropCallback = callback
return true
}
@objc public static func unregisterFileDropCallback() -> Bool {
fileDropCallback = nil
return true
}

View File

@@ -0,0 +1,123 @@
//
// OverlayView.swift
// LibUniWinC
//
// Created by Kirurobo on 2020/11/28.
// Copyright © 2020 Kirurobo. All rights reserved.
//
import Cocoa
protocol FileDroppedDelegate {
func complete(result: String)
}
class OverlayView: NSView {
// Reference: https://stackoverflow.com/questions/31657523/get-file-path-using-drag-and-drop-swift-macos
var pathsString: String = ""
var enabled = true
public func setEnabled(enabled: Bool) {
self.enabled = enabled
}
private func setup() {
self.registerForDraggedTypes(
[NSPasteboard.PasteboardType.URL, NSPasteboard.PasteboardType.fileURL]
)
}
public func fitToSuperView() -> Void {
if (superview == nil) {
return
}
// Fit to the parent frame
let constraints = [
self.centerXAnchor.constraint(equalTo: superview!.centerXAnchor),
self.centerYAnchor.constraint(equalTo: superview!.centerYAnchor),
self.widthAnchor.constraint(equalTo: superview!.widthAnchor),
self.heightAnchor.constraint(equalTo: superview!.heightAnchor)
]
NSLayoutConstraint.activate(constraints)
}
required init?(coder: NSCoder) {
super.init(coder: coder)
setup()
}
override init(frame: NSRect) {
super.init(frame: frame)
setup()
}
override func draggingEntered(_ sender: NSDraggingInfo) -> NSDragOperation {
if (self.enabled) {
return .copy
} else {
return .generic
}
}
override func performDragOperation(_ sender: NSDraggingInfo) -> Bool {
if (!self.enabled) {
return false
}
guard
let urls = sender.draggingPasteboard.propertyList(
forType: NSPasteboard.PasteboardType(rawValue: "NSFilenamesPboardType")
) as? NSArray
else {
return false
}
// Make new-line separated string
let files: String = urls.componentsJoined(by: "¥n")
guard let ustr = files.data(using: .utf8)
else {
return false
}
let buffer = UnsafeMutablePointer<uint8>.allocate(capacity: ustr.count + 1)
for i in 0..<ustr.count {
buffer[i] = ustr[i]
//buffer[i] = wchar_t.zero
}
buffer[ustr.count] = uint8.zero
// Do callback
LibUniWinC.fileDropCallback?(buffer)
buffer.deallocate()
// Store file paths
self.pathsString = files
return true
}
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
// Drawing code here.
NSColor.red.set()
let figure = NSBezierPath()
figure.move(to: dirtyRect.origin)
figure.line(to: NSMakePoint(dirtyRect.width, dirtyRect.height))
figure.line(to: NSMakePoint(dirtyRect.width - 5, dirtyRect.height))
figure.line(to: NSMakePoint(dirtyRect.width, dirtyRect.height - 5))
figure.line(to: NSMakePoint(dirtyRect.width, dirtyRect.height))
figure.lineWidth = 2
figure.stroke()
}
}
extension String {
func withWideChars<Result>(_ body: (UnsafePointer<wchar_t>) -> Result) -> Result {
let unicodestr = self.unicodeScalars.map { wchar_t(bitPattern: $0.value) } + [0]
return unicodestr.withUnsafeBufferPointer { body($0.baseAddress!) }
}
}