00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 @import <AppKit/CPView.j>
00024 @import <AppKit/CPEvent.j>
00025 @import <AppKit/CPPasteboard.j>
00026 @import <AppKit/CPImageView.j>
00027
00028
00029 var CPSharedDragServer = nil;
00030
00031 var CPDragServerView = nil,
00032 CPDragServerSource = nil,
00033 CPDragServerWindow = nil,
00034 CPDragServerOffset = nil,
00035 CPDragServerLocation = nil,
00036 CPDragServerPasteboard = nil,
00037 CPDragServerDestination = nil,
00038 CPDragServerDraggingInfo = nil;
00039
00040 var CPDragServerIsDraggingImage = NO,
00041
00042 CPDragServerShouldSendDraggedViewMovedTo = NO,
00043 CPDragServerShouldSendDraggedImageMovedTo = NO,
00044
00045 CPDragServerShouldSendDraggedViewEndedAtOperation = NO,
00046 CPDragServerShouldSendDraggedImageEndedAtOperation = NO;
00047
00048 var CPDragServerStartDragging = function(anEvent)
00049 {
00050 CPDragServerUpdateDragging(anEvent);
00051 }
00052
00053 var CPDragServerUpdateDragging = function(anEvent)
00054 {
00055
00056 if([anEvent type] == CPLeftMouseUp)
00057 {
00058 CPDragServerLocation = [[CPDragServerDestination window] convertBridgeToBase:[[anEvent window] convertBaseToBridge:[anEvent locationInWindow]]];
00059
00060 [CPDragServerView removeFromSuperview];
00061 [CPSharedDragServer._dragWindow orderOut:nil];
00062
00063 if (CPDragServerDestination &&
00064 (![CPDragServerDestination respondsToSelector:@selector(prepareForDragOperation:)] || [CPDragServerDestination prepareForDragOperation:CPDragServerDraggingInfo]) &&
00065 (![CPDragServerDestination respondsToSelector:@selector(performDragOperation:)] || [CPDragServerDestination performDragOperation:CPDragServerDraggingInfo]) &&
00066 [CPDragServerDestination respondsToSelector:@selector(concludeDragOperation:)])
00067 [CPDragServerDestination concludeDragOperation:CPDragServerDraggingInfo];
00068
00069 if (CPDragServerShouldSendDraggedImageEndedAtOperation)
00070 [CPDragServerSource draggedImage:[CPDragServerView image] endedAt:CPDragServerLocation operation:NO];
00071 else if (CPDragServerShouldSendDraggedViewEndedAtOperation)
00072 [CPDragServerSource draggedView:CPDragServerView endedAt:CPDragServerLocation operation:NO];
00073
00074 CPDragServerIsDraggingImage = NO;
00075 CPDragServerDestination = nil;
00076
00077 return;
00078 }
00079
00080
00081 [CPApp setCallback:CPDragServerUpdateDragging
00082 forNextEventMatchingMask:CPMouseMovedMask | CPLeftMouseDraggedMask | CPLeftMouseUpMask
00083 untilDate:nil inMode:0 dequeue:NO];
00084
00085 var location = [anEvent locationInWindow],
00086 operation =
00087 bridgeLocation = [[anEvent window] convertBaseToBridge:location];
00088
00089
00090 var draggingDestination = [[CPDOMWindowBridge sharedDOMWindowBridge] _dragHitTest:bridgeLocation pasteboard:CPDragServerPasteboard];
00091
00092 CPDragServerLocation = [[CPDragServerDestination window] convertBridgeToBase:bridgeLocation];
00093
00094 if(draggingDestination != CPDragServerDestination)
00095 {
00096 if (CPDragServerDestination && [CPDragServerDestination respondsToSelector:@selector(draggingExited:)])
00097 [CPDragServerDestination draggingExited:CPDragServerDraggingInfo];
00098
00099 CPDragServerDestination = draggingDestination;
00100
00101 if (CPDragServerDestination && [CPDragServerDestination respondsToSelector:@selector(draggingEntered:)])
00102 [CPDragServerDestination draggingEntered:CPDragServerDraggingInfo];
00103 }
00104 else if (CPDragServerDestination && [CPDragServerDestination respondsToSelector:@selector(draggingUpdated:)])
00105 [CPDragServerDestination draggingUpdated:CPDragServerDraggingInfo];
00106
00107 location.x -= CPDragServerOffset.x;
00108 location.y -= CPDragServerOffset.y;
00109
00110 [CPDragServerView setFrameOrigin:location];
00111
00112 if (CPDragServerShouldSendDraggedImageMovedTo)
00113 [CPDragServerSource draggedImage:[CPDragServerView image] movedTo:location];
00114 else if (CPDragServerShouldSendDraggedViewMovedTo)
00115 [CPDragServerSource draggedView:CPDragServerView movedTo:location];
00116 }
00117
00118
00119
00120
00121
00122 @implementation CPDraggingInfo : CPObject
00123 {
00124 CPWindow _window;
00125 }
00126
00127
00128
00129
00130 - (id)initWithWindow:(CPWindow)aWindow
00131 {
00132 self = [super init];
00133
00134 if (self)
00135 _window = aWindow;
00136
00137 return this;
00138 }
00139
00140 - (id)draggingSource
00141 {
00142 return CPDragServerSource;
00143 }
00144
00145 - (CPPoint)draggingLocation
00146 {
00147 return CPDragServerLocation;
00148 }
00149
00150 - (CPPasteboard)draggingPasteboard
00151 {
00152 return CPDragServerPasteboard;
00153 }
00154
00155 @end
00156
00157 @implementation CPDragServer : CPObject
00158 {
00159 CPWindow _dragWindow;
00160 CPImageView _imageView;
00161 }
00162
00163
00164
00165
00166
00167 + (void)initialize
00168 {
00169 if (self != [CPDragServer class])
00170 return;
00171
00172 CPDragServerDraggingInfo = [[CPDraggingInfo alloc] init];
00173 }
00174
00175 + (CPDragServer)sharedDragServer
00176 {
00177 if (!CPSharedDragServer)
00178 CPSharedDragServer = [[CPDragServer alloc] init];
00179
00180 return CPSharedDragServer;
00181 }
00182
00183
00184
00185
00186 - (id)init
00187 {
00188 self = [super init];
00189
00190 if (self)
00191 {
00192 _dragWindow = [[CPWindow alloc] initWithContentRect:CPRectMakeZero() styleMask:CPBorderlessWindowMask];
00193 [_dragWindow setLevel:CPDraggingWindowLevel];
00194 }
00195
00196 return self;
00197 }
00198
00211 - (void)dragView:(CPView)aView fromWindow:(CPWindow)aWindow at:(CGPoint)viewLocation offset:(CGSize)mouseOffset event:(CPEvent)anEvent pasteboard:(CPPasteboard)aPasteboard source:(id)aSourceObject slideBack:(BOOL)slideBack
00212 {
00213 var eventLocation = [anEvent locationInWindow];
00214
00215 CPDragServerView = aView;
00216 CPDragServerSource = aSourceObject;
00217 CPDragServerWindow = aWindow;
00218 CPDragServerOffset = CPPointMake(eventLocation.x - viewLocation.x, eventLocation.y - viewLocation.y);
00219 CPDragServerPasteboard = [CPPasteboard pasteboardWithName:CPDragPboard];
00220
00221 [_dragWindow setFrameSize:CGSizeMakeCopy([[CPDOMWindowBridge sharedDOMWindowBridge] frame].size)];
00222 [_dragWindow orderFront:self];
00223
00224 [aView setFrameOrigin:viewLocation];
00225 [[_dragWindow contentView] addSubview:aView];
00226
00227 if (CPDragServerIsDraggingImage)
00228 {
00229 if ([CPDragServerSource respondsToSelector:@selector(draggedImage:beganAt:)])
00230 [CPDragServerSource draggedImage:[aView image] beganAt:viewLocation];
00231
00232 CPDragServerShouldSendDraggedImageMovedTo = [CPDragServerSource respondsToSelector:@selector(draggedImage:movedTo:)];
00233 CPDragServerShouldSendDraggedImageEndedAtOperation = [CPDragServerSource respondsToSelector:@selector(draggedImage:endAt:operation:)];
00234
00235 CPDragServerShouldSendDraggedViewMovedTo = NO;
00236 CPDragServerShouldSendDraggedViewEndedAtOperation = NO;
00237 }
00238 else
00239 {
00240 if ([CPDragServerSource respondsToSelector:@selector(draggedView:beganAt:)])
00241 [CPDragServerSource draggedView:aView beganAt:viewLocation];
00242
00243 CPDragServerShouldSendDraggedViewMovedTo = [CPDragServerSource respondsToSelector:@selector(draggedView:movedTo:)];
00244 CPDragServerShouldSendDraggedViewEndedAtOperation = [CPDragServerSource respondsToSelector:@selector(draggedView:endedAt:operation:)];
00245
00246
00247 CPDragServerShouldSendDraggedImageMovedTo = NO;
00248 CPDragServerShouldSendDraggedImageEndedAtOperation = NO;
00249 }
00250
00251 CPDragServerStartDragging(anEvent);
00252 }
00253
00266 - (void)dragImage:(CPImage)anImage fromWindow:(CPWindow)aWindow at:(CGPoint)imageLocation offset:(CGSize)mouseOffset event:(CPEvent)anEvent pasteboard:(CPPasteboard)aPasteboard source:(id)aSourceObject slideBack:(BOOL)slideBack
00267 {
00268 CPDragServerIsDraggingImage = YES;
00269
00270 if (!_imageView)
00271 _imageView = [[CPImageView alloc] initWithFrame:CPRectMakeZero()];
00272
00273 [_imageView setImage:anImage];
00274 [_imageView setFrameSize:CGSizeMakeCopy([anImage size])];
00275
00276 [self dragView:_imageView fromWindow:aWindow at:imageLocation offset:mouseOffset event:anEvent pasteboard:aPasteboard source:aSourceObject slideBack:slideBack];
00277 }
00278
00279 @end
00280
00281 @implementation CPView (CPDraggingAdditions)
00282
00283
00284 - (CPView)_dragHitTest:(CPPoint)aPoint pasteboard:(CPPasteboard)aPasteboard
00285 {
00286 if(!CPRectContainsPoint(_frame, aPoint) || self == CPDragServerView)
00287 return nil;
00288
00289 var view = nil,
00290 i = [_subviews count],
00291 adjustedPoint = CPPointMake(aPoint.x - CPRectGetMinX(_frame), aPoint.y - CPRectGetMinY(_frame));
00292
00293 while (i--)
00294 if (view = [_subviews[i] _dragHitTest:adjustedPoint pasteboard:aPasteboard])
00295 return view;
00296
00297 if ([aPasteboard availableTypeFromArray:_registeredDraggedTypes])
00298 return self;
00299
00300 return nil;
00301 }
00302
00303 @end