@@ -1702,6 +1702,158 @@ - (void)keyUp:(NSEvent *)event {
1702
1702
}
1703
1703
1704
1704
1705
+ #pragma mark - Drag and Drop Events
1706
+
1707
+ enum DragEventType {
1708
+ DragEnter,
1709
+ DragLeave,
1710
+ Drop,
1711
+ };
1712
+
1713
+ - (void )buildDataTransferItems:(std::vector<DataTransferItem> &)dataTransferItems forPasteboard:(NSPasteboard *)pasteboard {
1714
+ NSArray *fileNames = [pasteboard propertyListForType: NSFilenamesPboardType ] ?: @[];
1715
+ for (NSString *file in fileNames) {
1716
+ NSURL *fileURL = [NSURL fileURLWithPath: file];
1717
+ BOOL isDir = NO ;
1718
+ BOOL isValid = (![[NSFileManager defaultManager ] fileExistsAtPath: fileURL.path isDirectory: &isDir] || isDir) ? NO : YES ;
1719
+ if (isValid) {
1720
+
1721
+ NSString *MIMETypeString = nil ;
1722
+ if (fileURL.pathExtension ) {
1723
+ CFStringRef fileExtension = (__bridge CFStringRef)fileURL.pathExtension ;
1724
+ CFStringRef UTI = UTTypeCreatePreferredIdentifierForTag (kUTTagClassFilenameExtension , fileExtension, NULL );
1725
+ if (UTI != NULL ) {
1726
+ CFStringRef MIMEType = UTTypeCopyPreferredTagWithClass (UTI, kUTTagClassMIMEType );
1727
+ CFRelease (UTI);
1728
+ MIMETypeString = (__bridge_transfer NSString *)MIMEType;
1729
+ }
1730
+ }
1731
+
1732
+ NSNumber *fileSizeValue = nil ;
1733
+ NSError *fileSizeError = nil ;
1734
+ BOOL success = [fileURL getResourceValue: &fileSizeValue
1735
+ forKey: NSURLFileSizeKey
1736
+ error: &fileSizeError];
1737
+
1738
+ NSNumber *width = nil ;
1739
+ NSNumber *height = nil ;
1740
+ if ([MIMETypeString hasPrefix: @" image/" ]) {
1741
+ NSImage *image = [[NSImage alloc ] initWithContentsOfURL: fileURL];
1742
+ width = @(image.size .width );
1743
+ height = @(image.size .height );
1744
+ }
1745
+
1746
+ DataTransferItem transferItem = {
1747
+ .name = fileURL.lastPathComponent .UTF8String ,
1748
+ .kind = " file" ,
1749
+ .type = MIMETypeString.UTF8String ,
1750
+ .uri = fileURL.path .UTF8String ,
1751
+ };
1752
+
1753
+ if (success) {
1754
+ transferItem.size = fileSizeValue.intValue ;
1755
+ }
1756
+
1757
+ if (width != nil ) {
1758
+ transferItem.width = width.intValue ;
1759
+ }
1760
+
1761
+ if (height != nil ) {
1762
+ transferItem.height = height.intValue ;
1763
+ }
1764
+
1765
+ dataTransferItems.push_back (transferItem);
1766
+ }
1767
+ }
1768
+
1769
+ NSPasteboardType imageType = [pasteboard availableTypeFromArray: @[NSPasteboardTypePNG , NSPasteboardTypeTIFF ]];
1770
+ if (imageType && fileNames.count == 0 ) {
1771
+ NSString *MIMETypeString = imageType == NSPasteboardTypePNG ? @" image/png" : @" image/tiff" ;
1772
+ NSData *imageData = [pasteboard dataForType: imageType];
1773
+ NSImage *image = [[NSImage alloc ] initWithData: imageData];
1774
+
1775
+ DataTransferItem transferItem = {
1776
+ .kind = " image" ,
1777
+ .type = MIMETypeString.UTF8String ,
1778
+ .uri = RCTDataURL (MIMETypeString, imageData).absoluteString .UTF8String ,
1779
+ .size = imageData.length ,
1780
+ .width = image.size .width ,
1781
+ .height = image.size .height ,
1782
+ };
1783
+
1784
+ dataTransferItems.push_back (transferItem);
1785
+ }
1786
+ }
1787
+
1788
+ - (void )sendDragEvent:(DragEventType)eventType withLocation:(NSPoint )locationInWindow pasteboard:(NSPasteboard *)pasteboard {
1789
+ if (!_eventEmitter) {
1790
+ return ;
1791
+ }
1792
+
1793
+ std::vector<DataTransferItem> dataTransferItems{};
1794
+ [self buildDataTransferItems: dataTransferItems forPasteboard: pasteboard];
1795
+
1796
+ NSPoint locationInView = [self convertPoint: locationInWindow fromView: nil ];
1797
+ NSEventModifierFlags modifierFlags = self.window .currentEvent .modifierFlags ;
1798
+
1799
+ DragEvent dragEvent = {
1800
+ {
1801
+ .clientX = locationInView.x ,
1802
+ .clientY = locationInView.y ,
1803
+ .screenX = locationInWindow.x ,
1804
+ .screenY = locationInWindow.y ,
1805
+ .altKey = static_cast <bool >(modifierFlags & NSEventModifierFlagOption),
1806
+ .ctrlKey = static_cast <bool >(modifierFlags & NSEventModifierFlagControl),
1807
+ .shiftKey = static_cast <bool >(modifierFlags & NSEventModifierFlagShift),
1808
+ .metaKey = static_cast <bool >(modifierFlags & NSEventModifierFlagCommand),
1809
+ },
1810
+ .dataTransferItems = dataTransferItems,
1811
+ };
1812
+
1813
+ switch (eventType) {
1814
+ case DragEnter:
1815
+ _eventEmitter->onDragEnter (dragEvent);
1816
+ break ;
1817
+
1818
+ case DragLeave:
1819
+ _eventEmitter->onDragLeave (dragEvent);
1820
+ break ;
1821
+
1822
+ case Drop:
1823
+ _eventEmitter->onDrop (dragEvent);
1824
+ break ;
1825
+ }
1826
+ }
1827
+
1828
+ - (NSDragOperation )draggingEntered:(id <NSDraggingInfo >)sender
1829
+ {
1830
+ NSPasteboard *pboard = sender.draggingPasteboard ;
1831
+ NSDragOperation sourceDragMask = sender.draggingSourceOperationMask ;
1832
+
1833
+ [self sendDragEvent: DragEnter withLocation: sender.draggingLocation pasteboard: pboard];
1834
+
1835
+ if ([pboard availableTypeFromArray: self .registeredDraggedTypes]) {
1836
+ if (sourceDragMask & NSDragOperationLink) {
1837
+ return NSDragOperationLink;
1838
+ } else if (sourceDragMask & NSDragOperationCopy) {
1839
+ return NSDragOperationCopy;
1840
+ }
1841
+ }
1842
+ return NSDragOperationNone;
1843
+ }
1844
+
1845
+ - (void )draggingExited:(id <NSDraggingInfo >)sender
1846
+ {
1847
+ [self sendDragEvent: DragLeave withLocation: sender.draggingLocation pasteboard: sender.draggingPasteboard];
1848
+ }
1849
+
1850
+ - (BOOL )performDragOperation:(id <NSDraggingInfo >)sender
1851
+ {
1852
+ [self sendDragEvent: Drop withLocation: sender.draggingLocation pasteboard: sender.draggingPasteboard];
1853
+ return YES ;
1854
+ }
1855
+
1856
+
1705
1857
#pragma mark - Mouse Events
1706
1858
1707
1859
- (void )emitMouseEvent {
0 commit comments