Fix for Dragging can happen across views.

Reviewed by me.
This commit is contained in:
Francisco Ryan Tolmasky I
2009-01-05 23:46:57 -08:00
parent 6a5bf822ab
commit d942ed415b
3 changed files with 62 additions and 39 deletions
+16 -28
View File
@@ -26,6 +26,8 @@
@import <AppKit/CPImageView.j>
#define DRAGGING_WINDOW(anObject) ([anObject isKindOfClass:[CPWindow class]] ? anObject : [anObject window])
var CPSharedDragServer = nil;
var CPDragServerView = nil,
@@ -55,7 +57,7 @@ var CPDragServerUpdateDragging = function(anEvent)
// If this is a mouse up, then complete the drag.
if([anEvent type] == CPLeftMouseUp)
{
CPDragServerLocation = [[CPDragServerDestination window] convertBridgeToBase:[[anEvent window] convertBaseToBridge:[anEvent locationInWindow]]];
CPDragServerLocation = [DRAGGING_WINDOW(CPDragServerDestination) convertBridgeToBase:[[anEvent window] convertBaseToBridge:[anEvent locationInWindow]]];
[CPDragServerView removeFromSuperview];
[CPSharedDragServer._dragWindow orderOut:nil];
@@ -89,7 +91,7 @@ var CPDragServerUpdateDragging = function(anEvent)
// We have to convert base to bridge since the drag event comes from the source window, not the drag window.
var draggingDestination = [[CPDOMWindowBridge sharedDOMWindowBridge] _dragHitTest:bridgeLocation pasteboard:CPDragServerPasteboard];
CPDragServerLocation = [[CPDragServerDestination window] convertBridgeToBase:bridgeLocation];
CPDragServerLocation = [DRAGGING_WINDOW(draggingDestination) convertBridgeToBase:bridgeLocation];
if(draggingDestination != CPDragServerDestination)
{
@@ -121,20 +123,6 @@ var CPDragServerUpdateDragging = function(anEvent)
*/
@implementation CPDraggingInfo : CPObject
{
CPWindow _window;
}
/*
Initializes the receiver with the window
*/
- (id)initWithWindow:(CPWindow)aWindow
{
self = [super init];
if (self)
_window = aWindow;
return this;
}
- (id)draggingSource
@@ -164,7 +152,7 @@ var CPDragServerUpdateDragging = function(anEvent)
- (CGPoint)draggedViewLocation
{
return [[CPDragServerDestination window] convertBridgeToBase:[CPDragServerView frame].origin];
return [DRAGGING_WINDOW(CPDragServerDestination) convertBridgeToBase:[CPDragServerView frame].origin];
}
- (CPView)draggedView
@@ -298,22 +286,22 @@ var CPDragServerUpdateDragging = function(anEvent)
@end
@implementation CPView (CPDraggingAdditions)
@implementation CPWindow (CPDraggingAdditions)
/* @ignore */
- (CPView)_dragHitTest:(CPPoint)aPoint pasteboard:(CPPasteboard)aPasteboard
- (id)_dragHitTest:(CPPoint)aPoint pasteboard:(CPPasteboard)aPasteboard
{
if(!CPRectContainsPoint(_frame, aPoint) || self == CPDragServerView)
if (![self containsPoint:aPoint])
return nil;
var view = nil,
i = [_subviews count],
adjustedPoint = CPPointMake(aPoint.x - CPRectGetMinX(_frame), aPoint.y - CPRectGetMinY(_frame));
while (i--)
if (view = [_subviews[i] _dragHitTest:adjustedPoint pasteboard:aPasteboard])
return view;
var hitView = [_windowView hitTest:aPoint];
while (hitView && ![aPasteboard availableTypeFromArray:[hitView registeredDraggedTypes]])
hitView = [hitView superview];
if (hitView)
return hitView;
if ([aPasteboard availableTypeFromArray:_registeredDraggedTypes])
return self;
+33
View File
@@ -273,6 +273,8 @@ var CPWindowSaveImage = nil,
CPUndoManager _undoManager;
CPURL _representedURL;
CPArray _registeredDraggedTypes;
// Bridge Support
#if PLATFORM(DOM)
DOMElement _DOMElement;
@@ -1210,6 +1212,32 @@ CPTexturedBackgroundWindowMask
[[CPDragServer sharedDragServer] dragView:aView fromWindow:self at:[self convertBaseToBridge:imageLocation] offset:mouseOffset event:anEvent pasteboard:aPasteboard source:aSourceObject slideBack:slideBack];
}
/*!
Sets the receiver's list of acceptable data types for a dragging operation.
@param pasteboardTypes an array of CPPasteboards
*/
- (void)registerForDraggedTypes:(CPArray)pasteboardTypes
{
_registeredDraggedTypes = [pasteboardTypes copy];
}
/*!
Returns an array of all types the receiver accepts for dragging operations.
@return an array of CPPasteBoards
*/
- (CPArray)registeredDraggedTypes
{
return _registeredDraggedTypes;
}
/*!
Resets the array of acceptable data types for a dragging operation.
*/
- (void)unregisterDraggedTypes
{
_registeredDraggedTypes = nil;
}
// Accessing Editing Status
/*!
@@ -1643,6 +1671,11 @@ CPTexturedBackgroundWindowMask
[[self undoManager] redo];
}
- (BOOL)containsPoint:(CGPoint)aPoint
{
return CGRectContainsPoint(_frame, aPoint);
}
@end
var interpolate = function(fromValue, toValue, progress)
+13 -11
View File
@@ -285,14 +285,13 @@ var CPDOMWindowGetFrame,
}
/* @ignore */
- (CPView)_dragHitTest:(CPPoint)aPoint pasteboard:(CPPasteboard)aPasteboard
- (id)_dragHitTest:(CPPoint)aPoint pasteboard:(CPPasteboard)aPasteboard
{
var view = nil,
levels = _windowLevels,
var levels = _windowLevels,
layers = _windowLayers,
levelCount = levels.length;
while (levelCount-- && !view)
while (levelCount--)
{
// Skip any windows above or at the dragging level.
if (levels[levelCount] >= CPDraggingWindowLevel)
@@ -303,18 +302,21 @@ var CPDOMWindowGetFrame,
while (windowCount--)
{
var theWindow = windows[windowCount],
frame = theWindow._frame;
var theWindow = windows[windowCount];
if (CPRectContainsPoint(frame, aPoint))
if (view = [theWindow._windowView _dragHitTest:CGPointMake(aPoint.x - frame.origin.x, aPoint.y - frame.origin.y) pasteboard:aPasteboard])
return view;
if ([theWindow containsPoint:aPoint])
{
var object = [theWindow _dragHitTest:aPoint pasteboard:aPasteboard];
if (object)
return object;
else
return nil;
}
}
}
return view;
return nil;
}
/* @ignore */
@@ -339,7 +341,7 @@ var CPDOMWindowGetFrame,
{
var candidateWindow = windows[windowCount];
if (!candidateWindow._ignoresMouseEvents && CGRectContainsPoint(candidateWindow._frame, location))
if (!candidateWindow._ignoresMouseEvents && [candidateWindow containsPoint:location])
theWindow = candidateWindow;
}
}