Last active
February 15, 2023 13:29
-
-
Save raphaelhanneken/d77b6f9b01bef35709da to your computer and use it in GitHub Desktop.
NSImageView with drag and drop capabilities written in Swift.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// DragAndDropImageView.swift | |
// Iconizer | |
// https://github.com/raphaelhanneken/iconizer | |
// | |
import Cocoa | |
class DragDropImageView: NSImageView, NSDraggingSource { | |
/// Holds the last mouse down event, to track the drag distance. | |
var mouseDownEvent: NSEvent? | |
override init(frame frameRect: NSRect) { | |
super.init(frame: frameRect) | |
// Assure editable is set to true, to enable drop capabilities. | |
isEditable = true | |
} | |
required init?(coder: NSCoder) { | |
super.init(coder: coder) | |
// Assure editable is set to true, to enable drop capabilities. | |
isEditable = true | |
} | |
override func draw(_ dirtyRect: NSRect) { | |
super.draw(dirtyRect) | |
} | |
// MARK: - NSDraggingSource | |
// Since we only want to copy/delete the current image we register ourselfes | |
// for .Copy and .Delete operations. | |
func draggingSession(_: NSDraggingSession, | |
sourceOperationMaskFor _: NSDraggingContext) -> NSDragOperation { | |
return NSDragOperation.copy.union(.delete) | |
} | |
// Clear the ImageView on delete operation; e.g. the image gets | |
// dropped on the trash can in the dock. | |
func draggingSession(_: NSDraggingSession, endedAt _: NSPoint, | |
operation: NSDragOperation) { | |
if operation == .delete { | |
image = nil | |
} | |
} | |
// Track mouse down events and safe the to the poperty. | |
override func mouseDown(with theEvent: NSEvent) { | |
mouseDownEvent = theEvent | |
} | |
// Track mouse dragged events to handle dragging sessions. | |
override func mouseDragged(with event: NSEvent) { | |
// Calculate the dragging distance... | |
let mouseDown = mouseDownEvent!.locationInWindow | |
let dragPoint = event.locationInWindow | |
let dragDistance = hypot(mouseDown.x - dragPoint.x, mouseDown.y - dragPoint.y) | |
// Cancel the dragging session in case of an accidental drag. | |
if dragDistance < 3 { | |
return | |
} | |
guard let image = self.image else { | |
return | |
} | |
// Do some math to properly resize the given image. | |
let size = NSSize(width: log10(image.size.width) * 30, height: log10(image.size.height) * 30) | |
if let draggingImage = image.resize(toSize: size, aspectMode: .fit) { | |
// Create a new NSDraggingItem with the image as content. | |
let draggingItem = NSDraggingItem(pasteboardWriter: image) | |
// Calculate the mouseDown location from the window's coordinate system to the | |
// ImageView's coordinate system, to use it as origin for the dragging frame. | |
let draggingFrameOrigin = convert(mouseDown, from: nil) | |
// Build the dragging frame and offset it by half the image size on each axis | |
// to center the mouse cursor within the dragging frame. | |
let draggingFrame = NSRect(origin: draggingFrameOrigin, size: draggingImage.size) | |
.offsetBy(dx: -draggingImage.size.width / 2, dy: -draggingImage.size.height / 2) | |
// Assign the dragging frame to the draggingFrame property of our dragging item. | |
draggingItem.draggingFrame = draggingFrame | |
// Provide the components of the dragging image. | |
draggingItem.imageComponentsProvider = { | |
let component = NSDraggingImageComponent(key: NSDraggingItem.ImageComponentKey.icon) | |
component.contents = image | |
component.frame = NSRect(origin: NSPoint(), size: draggingFrame.size) | |
return [component] | |
} | |
// Begin actual dragging session. Woohow! | |
beginDraggingSession(with: [draggingItem], event: mouseDownEvent!, source: self) | |
} | |
} | |
} |
Line 66
Value of type 'NSImage' has no member 'resize'
Apple's documentation (https://developer.apple.com/documentation/appkit/nsimage) confirms this. Has this been tested with Swift 3 / 4?
Line 66
Value of type 'NSImage' has no member 'resize'
Apple's documentation (https://developer.apple.com/documentation/appkit/nsimage) confirms this. Has this been tested with Swift 3 / 4?
@DesWurstes
I'am using this NSImageExtension, to resize the image.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Apple could use it… 😂