我知道这是一篇旧帖子,但我正在开发我的 Traktor Suggestions 程序。我已经完成了 95%,现在我只需要一种方法来允许用户选择一个文件,然后单击“加载到甲板 A”或“加载到甲板 B”。如您所知,Traktor 将接受拖动的文件。但我想将其自动化,因为当您进行 DJ 时,您触摸鼠标的次数越少越好。
我也对你一直在做的事情非常感兴趣。
我花了一点时间才弄清楚,但我意识到我需要创建一个粘贴板。因为我没有处理图像,只需要提供文件路径(作为 NSString ......我也可以使用 NSURL,但直接路径似乎最简单)。它们是用于创建粘贴板和拖动会话以及设置“拖动图像”等的多种方法。然后我遇到了最简单的形式,即使用简单的 NSView 函数(需要放置在 Mouse Down 函数中)。并且已经设置了 dragFilePath 变量。所以在我的自定义 NSView 中我有这个代码。您还需要有一个 NSImageView 作为自定义 NSView 的子视图。为了让这个“快速”功能发挥作用。
self dragFile.... 创建一个即时粘贴板项目,并且拖动会话都将输出多行代码。
- (void)mouseDown:(NSEvent*)theEvent {
NSLog(@"DRAGnDROP VIEW mouseDown happened");
NSLog(@"DRAGnDROP VIEW mouseDown dragFilePath is: %@", dragFilePath);
[self dragFile:dragFilePath fromRect:(self.bounds) slideBack:YES event:theEvent];
}
我有两个按钮可以触发 CGEvents。我在 Applescript 中有按钮运行功能。Applescript 函数触发鼠标向下,启动 drake,切换到 Traktor,然后将鼠标移动到甲板 A 或甲板 B,然后释放。
AppleScript 功能:
on loadTraktorDeckA:sender
deckDetailControllerDelegate's loadForDrag:me
delay 0.5
tell application "Traktor"
activate
end tell
deckDetailControllerDelegate's loadForReleaseA:me
end loadTraktorDeckA:
on loadTraktorDeckB:sender
deckDetailControllerDelegate's loadForDrag:me
delay 0.5
tell application "Traktor"
activate
end tell
deckDetailControllerDelegate's loadForReleaseB:me
end loadTraktorDeckB:
在自定义 NSView 中,这些是被调用的 CG 鼠标事件:
-(void)loadForDrag:(id)sender {
NSLog(@"mouse left drag called");
/* create a new Quartz mouse event.
* @source : CGEventSourceRef
* @mouseType : CGEventType
* @mouseCursorPosition : CGPoint
* @mouseButton : CGMouseButton
*/
CGEventSourceStateID kCGEventSourceStatePrivate = -1;
CGEventSourceRef loadDragEventRef = CGEventSourceCreate(kCGEventSourceStatePrivate);
CGPoint startPoint = CGPointMake(880.0, 770.0);
CGPoint movePoint1 = CGPointMake(610.0, 320.0);
CGEventRef leftDownEvent = CGEventCreateMouseEvent(loadDragEventRef, kCGEventLeftMouseDown, startPoint, 1);
CGEventRef leftDragEvent1 = CGEventCreateMouseEvent(loadDragEventRef, kCGEventLeftMouseDragged, startPoint, 0);
CGEventRef leftDragEvent2 = CGEventCreateMouseEvent(loadDragEventRef, kCGEventLeftMouseDragged, movePoint1, 0);
/* post a Quartz event into the event stream at a specified location.
* @tap : CGEventTapLocation
* @event : CGEventRef
*/
CGEventPost(kCGHIDEventTap, leftDragEvent2);
CGEventSourceSetLocalEventsSuppressionInterval(loadDragEventRef, 2);
CGEventPost(kCGHIDEventTap, leftDownEvent);
CGEventPost(kCGHIDEventTap, leftDragEvent1);
CGEventPost(kCGHIDEventTap, leftDragEvent2);
/**
* release a Quartz event
*/
// CFRelease(leftDragEvent);}
-(void)loadForReleaseA:(id)sender {
NSLog(@"mouse left Up called DECK A");
CGPoint movePoint1 = CGPointMake(610.0, 320.0);
CGPoint movePointRelease = CGPointMake(220.0, 320.0);
CGEventRef leftDragEvent2 = CGEventCreateMouseEvent(NULL, kCGEventLeftMouseDragged, movePoint1, 0);
CGEventPost(kCGHIDEventTap, leftDragEvent2);
CGEventRef leftClickUpEvent = CGEventCreateMouseEvent(NULL, kCGEventLeftMouseUp,movePointRelease, 0);
CGEventPost(kCGHIDEventTap, leftClickUpEvent);
/** release a Quartz event
*/
CFRelease(leftClickUpEvent);}
-(void)loadForReleaseB:(id)sender {
NSLog(@"mouse left Up called DECK B");
CGPoint movePoint1 = CGPointMake(610.0, 320.0);
CGPoint movePointRelease = CGPointMake(1000.0, 320.0);
CGEventRef leftDragEvent2 = CGEventCreateMouseEvent(NULL, kCGEventLeftMouseDragged, movePoint1, 0);
CGEventPost(kCGHIDEventTap, leftDragEvent2);
CGEventRef leftClickUpEvent = CGEventCreateMouseEvent(NULL, kCGEventLeftMouseUp,movePointRelease, 0);
CGEventPost(kCGHIDEventTap, leftClickUpEvent);
CFRelease(leftClickUpEvent);}
这是完整的自定义 DragNDropView 类
拖放视图.h
//
// DragNDropView.h
// DJK-Tel Traktor Suggestions
//
//
//
#import <Cocoa/Cocoa.h>
#import <Foundation/Foundation.h>
#import <AppKit/AppKit.h>
@interface DragNDropView : NSView <NSDraggingSource, NSDraggingDestination, NSImageDelegate, NSApplicationDelegate>
//NSPasteboardItemDataProvider
@property (nonatomic, strong) NSString* dragFilePath;
@property (nonatomic, strong) NSURL* dragFilePathURL;
- (id)initWithCoder:(NSCoder *)coder;
- (id)initWithFrame:(NSRect)frameRect;
- (void)mouseDown:(NSEvent*)theEvent;
-(IBAction)loadForDrag:(id)sender;
-(IBAction)loadForReleaseA:(id)sender;
-(IBAction)loadForReleaseB:(id)sender;
- (BOOL)shouldDelayWindowOrderingForEvent:(NSEvent *)event;
@end
拖放视图.m
// DragNDropView.m
// DJK-Tel Traktor Suggestions
//
//
//
#import "DragNDropView.h"
@implementation DragNDropView
@synthesize dragFilePath;
@synthesize dragFilePathURL;
- (id)initWithCoder:(NSCoder *)coder
{
/*------------------------------------------------------
Init method called for Interface Builder objects
--------------------------------------------------------*/
self=[super initWithCoder:coder];
if ( self ) {
NSLog(@"DRAGnDROP VIEW INIT WITH CODER happened");
//[self registerForDraggedTypes:[NSArray arrayWithObjects:@"NSFilenamesPboardType",@"NSURLPboardType",nil]];
[self initView];
}
return self;
}
- (id)initWithFrame:(NSRect)frame
{
self = [super initWithFrame:frame];
if (self) {
NSLog(@"DRAGnDROP VIEW INIT WITH FRAME happened");
[self initView];
}
return self;
}
- (void)setFrame:(NSRect)frameRect
{
[super setFrame:frameRect];
}
- (void) initView
{
NSLog(@"DRAGnDROP VIEW Init View");
dragFilePath = @"";
dragFilePathURL = nil;
}
- (void)drawRect:(NSRect)dirtyRect {
[super drawRect:dirtyRect];
// Drawing code here.
}
#pragma mark - Destination Operations
- (void)mouseDown:(NSEvent*)theEvent {
NSLog(@"DRAGnDROP VIEW mouseDown happened");
NSLog(@"DRAGnDROP VIEW mouseDown dragFilePath is: %@", dragFilePath);
[self dragFile:dragFilePath fromRect:(self.bounds) slideBack:YES event:theEvent];
}
- (BOOL)shouldDelayWindowOrderingForEvent:(NSEvent *)event {
return YES;
}
- (void)mouseDragged:(NSEvent *)event {
}
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender {
NSPasteboard *pboard = [sender draggingPasteboard];
//NSLog(@"DRAGnDROP VIEW performDragOperation pboard is: %@", pboard);
if ( [[pboard types] containsObject:NSFilenamesPboardType] ) {
NSArray *files = [pboard propertyListForType:NSFilenamesPboardType];
if ([files count] == 1) {
dragFilePath = files[1];
return YES;
}
}
else if ( [[pboard types] containsObject:NSURLPboardType] ) {
dragFilePathURL = [NSURL URLFromPasteboard:pboard];
NSLog(@"DRAGnDROP VIEW performDragOperation dragFilePathURL is: %@", dragFilePathURL);
return YES;
}
return NO;
}
-(void)loadForDrag:(id)sender {
NSLog(@"mouse left drag called");
/* create a new Quartz mouse event.
* @source : CGEventSourceRef
* @mouseType : CGEventType
* @mouseCursorPosition : CGPoint
* @mouseButton : CGMouseButton
*/
CGEventSourceStateID kCGEventSourceStatePrivate = -1;
CGEventSourceRef loadDragEventRef = CGEventSourceCreate(kCGEventSourceStatePrivate);
CGPoint startPoint = CGPointMake(880.0, 770.0);
CGPoint movePoint1 = CGPointMake(610.0, 320.0);
CGEventRef leftDownEvent = CGEventCreateMouseEvent(loadDragEventRef, kCGEventLeftMouseDown, startPoint, 1);
CGEventRef leftDragEvent1 = CGEventCreateMouseEvent(loadDragEventRef, kCGEventLeftMouseDragged, startPoint, 0);
CGEventRef leftDragEvent2 = CGEventCreateMouseEvent(loadDragEventRef, kCGEventLeftMouseDragged, movePoint1, 0);
/* post a Quartz event into the event stream at a specified location.
* @tap : CGEventTapLocation
* @event : CGEventRef
*/
CGEventPost(kCGHIDEventTap, leftDragEvent2);
CGEventSourceSetLocalEventsSuppressionInterval(loadDragEventRef, 2);
CGEventPost(kCGHIDEventTap, leftDownEvent);
CGEventPost(kCGHIDEventTap, leftDragEvent1);
CGEventPost(kCGHIDEventTap, leftDragEvent2);
/**
* release a Quartz event
*/
// CFRelease(leftDragEvent);
}
-(void)loadForReleaseA:(id)sender {
NSLog(@"mouse left Up called DECK A");
CGPoint movePoint1 = CGPointMake(610.0, 320.0);
CGPoint movePointRelease = CGPointMake(220.0, 320.0);
CGEventRef leftDragEvent2 = CGEventCreateMouseEvent(NULL, kCGEventLeftMouseDragged, movePoint1, 0);
CGEventPost(kCGHIDEventTap, leftDragEvent2);
CGEventRef leftClickUpEvent = CGEventCreateMouseEvent(NULL, kCGEventLeftMouseUp,movePointRelease, 0);
CGEventPost(kCGHIDEventTap, leftClickUpEvent);
CFRelease(leftClickUpEvent);
}
-(void)loadForReleaseB:(id)sender {
NSLog(@"mouse left Up called DECK B");
CGPoint movePoint1 = CGPointMake(610.0, 320.0);
CGPoint movePointRelease = CGPointMake(1000.0, 320.0);
CGEventRef leftDragEvent2 = CGEventCreateMouseEvent(NULL, kCGEventLeftMouseDragged, movePoint1, 0);
CGEventPost(kCGHIDEventTap, leftDragEvent2);
CGEventRef leftClickUpEvent = CGEventCreateMouseEvent(NULL, kCGEventLeftMouseUp,movePointRelease, 0);
CGEventPost(kCGHIDEventTap, leftClickUpEvent);
CFRelease(leftClickUpEvent);
}
#pragma mark - Source Operations
- (NSDragOperation)draggingSession:(NSDraggingSession *)session sourceOperationMaskForDraggingContext:(NSDraggingContext)context
{
/*------------------------------------------------------
NSDraggingSource protocol method. Returns the types of operations allowed in a certain context.
--------------------------------------------------------*/
switch (context) {
case NSDraggingContextOutsideApplication:
return NSDragOperationCopy;
//by using this fall through pattern, we will remain compatible if the contexts get more precise in the future.
case NSDraggingContextWithinApplication:
default:
return NSDragOperationCopy;
//return NSDragOperationNone;
break;
}
}
- (BOOL)acceptsFirstMouse:(NSEvent *)event
{
/*------------------------------------------------------
accept activation click as click in window
--------------------------------------------------------*/
//so source doesn't have to be the active window
return NO;
}
@end