diff --git a/AppKit/CPApplication.j b/AppKit/CPApplication.j index 54b424754..0593c6f0d 100644 --- a/AppKit/CPApplication.j +++ b/AppKit/CPApplication.j @@ -86,6 +86,7 @@ CPRunContinuesResponse = -1002; // id _delegate; + BOOL _finishedLaunching; CPDictionary _namedArgs; CPArray _args; @@ -268,15 +269,30 @@ CPRunContinuesResponse = -1002; [defaultCenter postNotificationName:CPApplicationWillFinishLaunchingNotification object:self]; - - if (_documentController) + + var filename = window.cpOpeningFilename(), + needsUntitled = !!_documentController; + + if ([filename length]) + { + [self _openFile:filename]; + + needsUntitled = NO; + } + + if (needsUntitled && [_delegate respondsToSelector: @selector(applicationShouldOpenUntitledFile:)]) + needsUntitled = [_delegate applicationShouldOpenUntitledFile:self]; + + if (needsUntitled) [_documentController newDocument:self]; [defaultCenter postNotificationName:CPApplicationDidFinishLaunchingNotification object:self]; - + [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode]; + + _finishedLaunching = YES; } /*! @@ -403,6 +419,8 @@ CPRunContinuesResponse = -1002; */ - (void)sendEvent:(CPEvent)anEvent { + _currentEvent = anEvent; + // Check if this is a candidate for key equivalent... if ([anEvent type] == CPKeyDown && [anEvent modifierFlags] & (CPCommandKeyMask | CPControlKeyMask) && @@ -670,6 +688,11 @@ CPRunContinuesResponse = -1002; _eventListeners.push(_CPEventListenerMake(aMask, function (anEvent) { objj_msgSend(aTarget, aSelector, anEvent); })); } +- (CPEvent)currentEvent +{ + return _currentEvent; +} + // Managing Sheets /*! @@ -733,6 +756,11 @@ CPRunContinuesResponse = -1002; return _namedArgs; } +- (void)_openFile:(CPString)aFilename +{ + [_documentController openDocumentWithContentsOfURL:aFilename display:YES error:NULL]; +} + @end var _CPModalSessionMake = function(aWindow, aStopCode) diff --git a/AppKit/CPCollectionView.j b/AppKit/CPCollectionView.j index b1f3952b8..f206d1473 100644 --- a/AppKit/CPCollectionView.j +++ b/AppKit/CPCollectionView.j @@ -93,6 +93,8 @@ unsigned _numberOfColumns; id _delegate; + + CPEvent _mouseDownEvent; } - (id)initWithFrame:(CGRect)aFrame @@ -528,13 +530,16 @@ - (void)mouseDown:(CPEvent)anEvent { + _mouseDownEvent = anEvent; + var location = [self convertPoint:[anEvent locationInWindow] fromView:nil], row = FLOOR(location.y / (_itemSize.height + _verticalMargin)), column = FLOOR(location.x / (_itemSize.width + _horizontalMargin)), index = row * _numberOfColumns + column; - + if (index >= 0 && index < _items.length) [self setSelectionIndexes:[CPIndexSet indexSetWithIndex:index]]; + else if (_allowsEmptySelection) [self setSelectionIndexes:[CPIndexSet indexSet]]; } @@ -566,7 +571,7 @@ [self dragView:view at:[[_items[[_selectionIndexes firstIndex]] view] frame].origin offset:CGPointMakeZero() - event:anEvent + event:_mouseDownEvent pasteboard:nil source:self slideBack:YES]; diff --git a/AppKit/CPCompatibility.j b/AppKit/CPCompatibility.j index e5e30c41f..b381cd359 100644 --- a/AppKit/CPCompatibility.j +++ b/AppKit/CPCompatibility.j @@ -35,17 +35,18 @@ CPCSSRGBAFeature = 1 << 5; CPHTMLCanvasFeature = 1 << 6; CPHTMLContentEditableFeature = 1 << 7; +CPHTMLDragAndDropFeature = 1 << 8; -CPJavascriptInnerTextFeature = 1 << 8; -CPJavascriptTextContentFeature = 1 << 9; -CPJavascriptClipboardEventsFeature = 1 << 10; -CPJavascriptClipboardAccessFeature = 1 << 11; -CPJavaScriptCanvasDrawFeature = 1 << 12; -CPJavaScriptCanvasTransformFeature = 1 << 13; +CPJavascriptInnerTextFeature = 1 << 9; +CPJavascriptTextContentFeature = 1 << 10; +CPJavascriptClipboardEventsFeature = 1 << 11; +CPJavascriptClipboardAccessFeature = 1 << 12; +CPJavaScriptCanvasDrawFeature = 1 << 13; +CPJavaScriptCanvasTransformFeature = 1 << 14; -CPVMLFeature = 1 << 14; +CPVMLFeature = 1 << 15; -CPJavascriptRemedialKeySupport = 1 << 15; +CPJavascriptRemedialKeySupport = 1 << 16; CPJavaScriptShadowFeature = 1 << 20; CPJavaScriptNegativeMouseWheelValues = 1 << 22; @@ -54,7 +55,8 @@ CPJavaScriptMouseWheelValues_8_15 = 1 << 23 CPOpacityRequiresFilterFeature = 1 << 24; //Internet explorer does not allow dynamically changing the type of an input element -CPInputTypeCanBeChangedFeature = 1 << 25; +CPInputTypeCanBeChangedFeature = 1 << 25; + @@ -100,6 +102,7 @@ else if (USER_AGENT.indexOf("AppleWebKit/") != -1) // Features we can only be sure of with WebKit (no known independent tests) PLATFORM_FEATURES |= CPCSSRGBAFeature; PLATFORM_FEATURES |= CPHTMLContentEditableFeature; + PLATFORM_FEATURES |= CPHTMLDragAndDropFeature; PLATFORM_FEATURES |= CPJavascriptClipboardEventsFeature; PLATFORM_FEATURES |= CPJavascriptClipboardAccessFeature; PLATFORM_FEATURES |= CPJavaScriptShadowFeature; diff --git a/AppKit/CPDragServer.j b/AppKit/CPDragServer.j index a341ddc90..9697a18d2 100644 --- a/AppKit/CPDragServer.j +++ b/AppKit/CPDragServer.j @@ -29,71 +29,25 @@ #import "Platform/Platform.h" +CPDragOperationNone = 0, +CPDragOperationCopy = 1 << 1, +CPDragOperationLink = 1 << 1, +CPDragOperationGeneric = 1 << 2, +CPDragOperationPrivate = 1 << 3, +CPDragOperationMove = 1 << 4, +CPDragOperationDelete = 1 << 5, +CPDragOperationEvery = -1; + #define DRAGGING_WINDOW(anObject) ([anObject isKindOfClass:[CPWindow class]] ? anObject : [anObject window]) -var CPSharedDragServer = nil; - -var CPDragServerView = nil, - CPDragServerSource = nil, - CPDragServerWindow = nil, - CPDragServerOffset = nil, - CPDragServerLocation = nil, - CPDragServerPasteboard = nil, - CPDragServerDestination = nil, - CPDragServerDraggingInfo = nil, - CPDragServerPreviousEvent = nil, - CPDragServerAutoscrollInterval = nil; - -var CPDragServerIsDraggingImage = NO, - - CPDragServerShouldSendDraggedViewMovedTo = NO, - CPDragServerShouldSendDraggedImageMovedTo = NO, - - CPDragServerShouldSendDraggedViewEndedAtOperation = NO, - CPDragServerShouldSendDraggedImageEndedAtOperation = NO; - +var CPDragServerPreviousEvent = nil, +CPDragServerAutoscrollInterval = nil; +/* var CPDragServerAutoscroll = function() { [CPDragServerSource autoscroll:CPDragServerPreviousEvent]; } -var CPDragServerStartDragging = function(anEvent) -{ - CPDragServerUpdateDragging(anEvent); -} - -var CPDragServerUpdateDragging = function(anEvent) -{ - // If this is a mouse up, then complete the drag. - if([anEvent type] == CPLeftMouseUp) - { - if (CPDragServerAutoscrollInterval !== nil) - clearInterval(CPDragServerAutoscrollInterval); - - CPDragServerAutoscrollInterval = nil; - - CPDragServerLocation = [DRAGGING_WINDOW(CPDragServerDestination) convertBridgeToBase:[[anEvent window] convertBaseToBridge:[anEvent locationInWindow]]]; - - [CPDragServerView removeFromSuperview]; - [CPSharedDragServer._dragWindow orderOut:nil]; - - if (CPDragServerDestination && - (![CPDragServerDestination respondsToSelector:@selector(prepareForDragOperation:)] || [CPDragServerDestination prepareForDragOperation:CPDragServerDraggingInfo]) && - (![CPDragServerDestination respondsToSelector:@selector(performDragOperation:)] || [CPDragServerDestination performDragOperation:CPDragServerDraggingInfo]) && - [CPDragServerDestination respondsToSelector:@selector(concludeDragOperation:)]) - [CPDragServerDestination concludeDragOperation:CPDragServerDraggingInfo]; - - if (CPDragServerShouldSendDraggedImageEndedAtOperation) - [CPDragServerSource draggedImage:[CPDragServerView image] endedAt:CPDragServerLocation operation:NO]; - else if (CPDragServerShouldSendDraggedViewEndedAtOperation) - [CPDragServerSource draggedView:CPDragServerView endedAt:CPDragServerLocation operation:NO]; - - CPDragServerIsDraggingImage = NO; - CPDragServerDestination = nil; - - return; - } - if (CPDragServerAutoscrollInterval === nil) { if ([CPDragServerSource respondsToSelector:@selector(autoscroll:)]) @@ -102,43 +56,16 @@ var CPDragServerUpdateDragging = function(anEvent) CPDragServerPreviousEvent = anEvent; - // If we're not a mouse up, then we're going to want to grab the next event. - [CPApp setCallback:CPDragServerUpdateDragging - forNextEventMatchingMask:CPMouseMovedMask | CPLeftMouseDraggedMask | CPLeftMouseUpMask - untilDate:nil inMode:0 dequeue:NO]; + if (CPDragServerAutoscrollInterval !== nil) + clearInterval(CPDragServerAutoscrollInterval); - var location = [anEvent locationInWindow], - operation = - bridgeLocation = [[anEvent window] convertBaseToBridge:location]; + CPDragServerAutoscrollInterval = nil; +*/ - // We have to convert base to bridge since the drag event comes from the source window, not the drag window. - var draggingDestination = [[CPPlatformWindow primaryPlatformWindow] _dragHitTest:bridgeLocation pasteboard:CPDragServerPasteboard]; - - CPDragServerLocation = [DRAGGING_WINDOW(draggingDestination) convertBridgeToBase:bridgeLocation]; - - if(draggingDestination != CPDragServerDestination) - { - if (CPDragServerDestination && [CPDragServerDestination respondsToSelector:@selector(draggingExited:)]) - [CPDragServerDestination draggingExited:CPDragServerDraggingInfo]; - - CPDragServerDestination = draggingDestination; - - if (CPDragServerDestination && [CPDragServerDestination respondsToSelector:@selector(draggingEntered:)]) - [CPDragServerDestination draggingEntered:CPDragServerDraggingInfo]; - } - else if (CPDragServerDestination && [CPDragServerDestination respondsToSelector:@selector(draggingUpdated:)]) - [CPDragServerDestination draggingUpdated:CPDragServerDraggingInfo]; - - location.x -= CPDragServerOffset.x; - location.y -= CPDragServerOffset.y; - - [CPDragServerView setFrameOrigin:location]; - - if (CPDragServerShouldSendDraggedImageMovedTo) - [CPDragServerSource draggedImage:[CPDragServerView image] movedTo:location]; - else if (CPDragServerShouldSendDraggedViewMovedTo) - [CPDragServerSource draggedView:CPDragServerView movedTo:location]; -} +var CPSharedDragServer = nil; + +var CPDragServerSource = nil; +var CPDragServerDraggingInfo = nil; /* CPDraggingInfo is a container of information about a specific dragging session. @@ -148,24 +75,36 @@ var CPDragServerUpdateDragging = function(anEvent) { } +- (CPPasteboard)draggingPasteboard +{ + if ([CPPlatform supportsDragAndDrop]) + return [_CPDOMDataTransferPasteboard DOMDataTransferPasteboard]; + + return [[CPDragServer sharedDragServer] draggingPasteboard]; +} + - (id)draggingSource { - return CPDragServerSource; + return [[CPDragServer sharedDragServer] draggingSource]; } +/* +- (unsigned)draggingSourceOperationMask +*/ + - (CPPoint)draggingLocation { - return CPDragServerLocation; + return [[CPDragServer sharedDragServer] draggingLocation]; } -- (CPPasteboard)draggingPasteboard +- (CPWindow)draggingDestinationWindow { - return CPDragServerPasteboard; + return DRAGGING_WINDOW([[CPDragServer sharedDragServer] draggingDestination]); } - (CPImage)draggedImage { - return [CPDragServerView image]; + return [[self draggedView] image]; } - (CGPoint)draggedImageLocation @@ -173,22 +112,44 @@ var CPDragServerUpdateDragging = function(anEvent) return [self draggedViewLocation]; } -- (CGPoint)draggedViewLocation -{ - return [DRAGGING_WINDOW(CPDragServerDestination) convertBridgeToBase:[CPDragServerView frame].origin]; -} - - (CPView)draggedView { - return CPDragServerView; + return [[CPDragServer sharedDragServer] draggedView]; +} + +- (CGPoint)draggedViewLocation +{ + var dragServer = [CPDragServer sharedDragServer]; + + return [DRAGGING_WINDOW([dragServer draggingDestination]) convertPlatformWindowToBase:[[dragServer draggedView] frame].origin]; } @end +var CPDraggingSource_draggedImage_movedTo_ = 1 << 0, + CPDraggingSource_draggedImage_endAt_operation_ = 1 << 1, + CPDraggingSource_draggedView_movedTo_ = 1 << 2, + CPDraggingSource_draggedView_endedAt_operation_ = 1 << 3; + @implementation CPDragServer : CPObject { - CPWindow _dragWindow; - CPImageView _imageView; + BOOL _isDragging @accessors(readonly, getter=isDragging); + + CPWindow _draggedWindow @accessors(readonly, getter=draggedWindow); + CPView _draggedView @accessors(readonly, getter=draggedView); + CPImageView _imageView; + + BOOL _isDraggingImage; + + CGSize _draggingOffset @accessors(readonly, getter=draggingOffset); + + CPPasteboard _draggingPasteboard @accessors(readonly, getter=draggingPasteboard); + + id _draggingSource @accessors(readonly, getter=draggingSource); + unsigned _implementedDraggingSourceMethods; + + CGPoint _draggingLocation; + id _draggingDestination; } /* @@ -197,9 +158,9 @@ var CPDragServerUpdateDragging = function(anEvent) */ + (void)initialize { - if (self != [CPDragServer class]) + if (self !== [CPDragServer class]) return; - + CPDragServerDraggingInfo = [[CPDraggingInfo alloc] init]; } @@ -207,7 +168,7 @@ var CPDragServerUpdateDragging = function(anEvent) { if (!CPSharedDragServer) CPSharedDragServer = [[CPDragServer alloc] init]; - + return CPSharedDragServer; } @@ -217,16 +178,104 @@ var CPDragServerUpdateDragging = function(anEvent) - (id)init { self = [super init]; - + if (self) { - _dragWindow = [[CPWindow alloc] initWithContentRect:CPRectMakeZero() styleMask:CPBorderlessWindowMask]; - [_dragWindow setLevel:CPDraggingWindowLevel]; + _draggedWindow = [[CPWindow alloc] initWithContentRect:_CGRectMakeZero() styleMask:CPBorderlessWindowMask]; + + [_draggedWindow setLevel:CPDraggingWindowLevel]; } - + return self; } +- (CGPoint)draggingLocation +{ + return _draggingLocation +} + +- (void)draggingStartedInPlatformWindow:(CPPlatformWindow)aPlatformWindow location:(CGPoint)aLocation +{ + if (_isDraggingImage) + { + if ([_draggingSource respondsToSelector:@selector(draggedImage:beganAt:)]) + [_draggingSource draggedImage:[_draggedView image] beganAt:aLocation]; + } + else + { + if ([_draggingSource respondsToSelector:@selector(draggedView:beganAt:)]) + [_draggingSource draggedView:_draggedView beganAt:aLocation]; + } + + if (![CPPlatform supportsDragAndDrop]) + [_draggedWindow orderFront:self]; +} + +- (void)draggingSourceUpdatedWithLocation:(CGPoint)aGlobalLocation +{ + if (![CPPlatform supportsDragAndDrop]) + [_draggedWindow setFrameOrigin:_CGPointMake(aGlobalLocation.x - _draggingOffset.width, aGlobalLocation.y - _draggingOffset.height)]; + + if (_implementedDraggingSourceMethods & CPDraggingSource_draggedImage_movedTo_) + [_draggingSource draggedImage:[_draggedView image] movedTo:aGlobalLocation]; + + else if (_implementedDraggingSourceMethods & CPDraggingSource_draggedView_movedTo_) + [_draggingSource draggedView:_draggedView movedTo:aGlobalLocation]; +} + +- (CPDragOperation)draggingUpdatedInPlatformWindow:(CPPlatformWindow)aPlatformWindow location:(CGPoint)aLocation +{ + var dragOperation = CPDragOperationCopy; + // We have to convert base to bridge since the drag event comes from the source window, not the drag window. + var draggingDestination = [aPlatformWindow _dragHitTest:aLocation pasteboard:[CPDragServerDraggingInfo draggingPasteboard]]; + + if (draggingDestination) + _draggingLocation = [DRAGGING_WINDOW(draggingDestination) convertPlatformWindowToBase:aLocation]; + + if(draggingDestination !== _draggingDestination) + { + if (_draggingDestination && [_draggingDestination respondsToSelector:@selector(draggingExited:)]) + [_draggingDestination draggingExited:CPDragServerDraggingInfo]; + + _draggingDestination = draggingDestination; + + if (_draggingDestination && [_draggingDestination respondsToSelector:@selector(draggingEntered:)]) + dragOperation = [_draggingDestination draggingEntered:CPDragServerDraggingInfo]; + } + else if (_draggingDestination && [_draggingDestination respondsToSelector:@selector(draggingUpdated:)]) + dragOperation = [_draggingDestination draggingUpdated:CPDragServerDraggingInfo]; + + if (!_draggingDestination) + dragOperation = CPDragOperationNone; + + return dragOperation; +} + +- (void)draggingEndedInPlatformWindow:(CPPlatformWindow)aPlatformWindow +{ + [_draggedView removeFromSuperview]; + + if (![CPPlatform supportsDragAndDrop]) + [_draggedWindow orderOut:self]; + + if (_implementedDraggingSourceMethods & CPDraggingSource_draggedImage_endAt_operation_) + [_draggingSource draggedImage:[_draggedView image] endedAt:_draggingLocation operation:NO]; + + else if (_implementedDraggingSourceMethods & CPDraggingSource_draggedView_endedAt_operation_) + [_draggingSource draggedView:_draggedView endedAt:_draggingLocation operation:NO]; + + _isDragging = NO; +} + +- (void)performDragOperationInPlatformWindow:(CPPlatformWindow)aPlatformWindow +{ + if (_draggingDestination && + (![_draggingDestination respondsToSelector:@selector(prepareForDragOperation:)] || [_draggingDestination prepareForDragOperation:CPDragServerDraggingInfo]) && + (![_draggingDestination respondsToSelector:@selector(performDragOperation:)] || [_draggingDestination performDragOperation:CPDragServerDraggingInfo]) && + [_draggingDestination respondsToSelector:@selector(concludeDragOperation:)]) + [_draggingDestination concludeDragOperation:CPDragServerDraggingInfo]; +} + /*! Initiates a drag session. @param aView the view being dragged @@ -239,54 +288,67 @@ var CPDragServerUpdateDragging = function(anEvent) @param slideBack if \c YES, \c aView slides back to its origin on a failed drop */ -- (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 +- (void)dragView:(CPView)aView fromWindow:(CPWindow)aWindow at:(CGPoint)viewLocation offset:(CGSize)mouseOffset event:(CPEvent)mouseDownEvent pasteboard:(CPPasteboard)aPasteboard source:(id)aSourceObject slideBack:(BOOL)slideBack { - var eventLocation = [anEvent locationInWindow]; + _isDragging = YES; - CPDragServerView = aView; - CPDragServerSource = aSourceObject; - CPDragServerWindow = aWindow; - CPDragServerOffset = CPPointMake(eventLocation.x - viewLocation.x, eventLocation.y - viewLocation.y); - CPDragServerPasteboard = [CPPasteboard pasteboardWithName:CPDragPboard];//aPasteboard; + _draggedView = aView; + _draggingPasteboard = aPasteboard || [CPPasteboard pasteboardWithName:CPDragPboard]; + _draggingSource = aSourceObject; + _draggingDestination = nil; -#if PLATFORM(BROWSER) - var platformWindow = [aWindow platformWindow]; + // The offset is based on the distance from where we want the view to be initially from where the mouse is initially + // Hence the use of mouseDownEvent's location and view's location in global coordinates. + var mouseDownWindow = [mouseDownEvent window], + mouseDownEventLocation = [mouseDownEvent locationInWindow]; - // FIXME: We should just have the window be the size of the view and move the window around. - [_dragWindow setPlatformWindow:platformWindow]; - [_dragWindow setFrameSize:[platformWindow contentBounds].size]; -#endif - - [_dragWindow orderFront:self]; - - [aView setFrameOrigin:viewLocation]; - [[_dragWindow contentView] addSubview:aView]; - - if (CPDragServerIsDraggingImage) + if (mouseDownEventLocation) { - if ([CPDragServerSource respondsToSelector:@selector(draggedImage:beganAt:)]) - [CPDragServerSource draggedImage:[aView image] beganAt:viewLocation]; - - CPDragServerShouldSendDraggedImageMovedTo = [CPDragServerSource respondsToSelector:@selector(draggedImage:movedTo:)]; - CPDragServerShouldSendDraggedImageEndedAtOperation = [CPDragServerSource respondsToSelector:@selector(draggedImage:endAt:operation:)]; - - CPDragServerShouldSendDraggedViewMovedTo = NO; - CPDragServerShouldSendDraggedViewEndedAtOperation = NO; + if (mouseDownWindow) + mouseDownEventLocation = [mouseDownWindow convertBaseToGlobal:mouseDownEventLocation]; + + _draggingOffset = _CGSizeMake(mouseDownEventLocation.x - viewLocation.x, mouseDownEventLocation.y - viewLocation.y); + } + else + _draggingOffset = _CGSizeMakerZero(); + + if ([CPPlatform isBrowser]) + [_draggedWindow setPlatformWindow:[aWindow platformWindow]]; + + [aView setFrameOrigin:_CGPointMakeZero()]; + + var mouseLocation = [CPEvent mouseLocation]; + + // Place it where the mouse pointer is. + [_draggedWindow setFrameOrigin:_CGPointMake(mouseLocation.x - _draggingOffset.width, mouseLocation.y - _draggingOffset.height)]; + [_draggedWindow setFrameSize:[aView frame].size]; + + [[_draggedWindow contentView] addSubview:aView]; + + _implementedDraggingSourceMethods = 0; + + if (_draggedView === _imageView) + { + if ([_draggingSource respondsToSelector:@selector(draggedImage:movedTo:)]) + _implementedDraggingSourceMethods |= CPDraggingSource_draggedImage_movedTo_; + + if ([_draggingSource respondsToSelector:@selector(draggedImage:endAt:operation:)]) + _implementedDraggingSourceMethods |= CPDraggingSource_draggedImage_endAt_operation_; } else { - if ([CPDragServerSource respondsToSelector:@selector(draggedView:beganAt:)]) - [CPDragServerSource draggedView:aView beganAt:viewLocation]; - - CPDragServerShouldSendDraggedViewMovedTo = [CPDragServerSource respondsToSelector:@selector(draggedView:movedTo:)]; - CPDragServerShouldSendDraggedViewEndedAtOperation = [CPDragServerSource respondsToSelector:@selector(draggedView:endedAt:operation:)]; - + if ([_draggingSource respondsToSelector:@selector(draggedView:movedTo:)]) + _implementedDraggingSourceMethods |= CPDraggingSource_draggedView_movedTo_; - CPDragServerShouldSendDraggedImageMovedTo = NO; - CPDragServerShouldSendDraggedImageEndedAtOperation = NO; + if ([_draggingSource respondsToSelector:@selector(draggedView:endedAt:operation:)]) + _implementedDraggingSourceMethods |= CPDraggingSource_draggedView_endedAt_operation_; } - CPDragServerStartDragging(anEvent); + if (![CPPlatform supportsDragAndDrop]) + { + [self draggingStartedInPlatformWindow:[aWindow platformWindow] location:mouseLocation]; + [self trackDragging:mouseDownEvent]; + } } /*! @@ -303,17 +365,42 @@ var CPDragServerUpdateDragging = function(anEvent) */ - (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 { - CPDragServerIsDraggingImage = YES; - + _isDraggingImage = YES; + + var imageSize = [anImage size]; + if (!_imageView) - _imageView = [[CPImageView alloc] initWithFrame:CPRectMakeZero()]; - + _imageView = [[CPImageView alloc] initWithFrame:_CGRectMake(0.0, 0.0, imageSize.width, imageSize.height)]; + [_imageView setImage:anImage]; - [_imageView setFrameSize:CGSizeMakeCopy([anImage size])]; - + [self dragView:_imageView fromWindow:aWindow at:imageLocation offset:mouseOffset event:anEvent pasteboard:aPasteboard source:aSourceObject slideBack:slideBack]; } +- (void)trackDragging:(CPEvent)anEvent +{ + var type = [anEvent type], + platformWindow = [_draggedWindow platformWindow], + platformWindowLocation = [[anEvent window] convertBaseToPlatformWindow:[anEvent locationInWindow]]; + + if (type === CPLeftMouseUp) + { + [self performDragOperationInPlatformWindow:platformWindow]; + [self draggingEndedInPlatformWindow:platformWindow]; + + // Stop tracking events. + return; + } + + [self draggingSourceUpdatedWithLocation:platformWindowLocation]; + [self draggingUpdatedInPlatformWindow:platformWindow location:platformWindowLocation]; + + // If we're not a mouse up, then we're going to want to grab the next event. + [CPApp setTarget:self selector:@selector(trackDragging:) + forNextEventMatchingMask:CPMouseMovedMask | CPLeftMouseDraggedMask | CPLeftMouseUpMask + untilDate:nil inMode:0 dequeue:NO]; +} + @end @implementation CPWindow (CPDraggingAdditions) @@ -331,18 +418,18 @@ var CPDragServerUpdateDragging = function(anEvent) // if (![self containsPoint:aPoint]) // return nil; - var adjustedPoint = _CGPointMake(aPoint.x - _CGRectGetMinX(_frame), aPoint.y - _CGRectGetMinY(_frame)), + var adjustedPoint = [self convertPlatformWindowToBase:aPoint], hitView = [_windowView hitTest:adjustedPoint]; while (hitView && ![aPasteboard availableTypeFromArray:[hitView registeredDraggedTypes]]) hitView = [hitView superview]; - + if (hitView) return hitView; - + if ([aPasteboard availableTypeFromArray:[self registeredDraggedTypes]]) return self; - + return nil; } diff --git a/AppKit/CPEvent.j b/AppKit/CPEvent.j index 37ba58358..eb942a79f 100644 --- a/AppKit/CPEvent.j +++ b/AppKit/CPEvent.j @@ -465,6 +465,18 @@ var _CPEventPeriodicEventPeriod = 0, return _keyCode; } ++ (CGPoint)mouseLocation +{ + // FIXME: this is incorrect, we shouldn't depend on the current event. + var event = [CPApp currentEvent], + eventWindow = [event window]; + + if (eventWindow) + return [eventWindow convertBaseToGlobal:[event locationInWindow]]; + + return [event locationInWindow]; +} + - (float)pressure { return _pressure; diff --git a/AppKit/CPImageView.j b/AppKit/CPImageView.j index c75187073..ed6eeea42 100644 --- a/AppKit/CPImageView.j +++ b/AppKit/CPImageView.j @@ -87,7 +87,13 @@ var LEFT_SHADOW_INSET = 3.0, _DOMImageElement.style.position = "absolute"; _DOMImageElement.style.left = "0px"; _DOMImageElement.style.top = "0px"; - + + if ([CPPlatform supportsDragAndDrop]) + { + _DOMImageElement.setAttribute("draggable", "true"); + _DOMImageElement.style["-khtml-user-drag"] = "element"; + } + CPDOMDisplayServerAppendChild(_DOMElement, _DOMImageElement); _DOMImageElement.style.visibility = "hidden"; @@ -398,6 +404,11 @@ var CPImageViewImageKey = @"CPImageViewImageKey", _DOMImageElement.style.left = "0px"; _DOMImageElement.style.top = "0px"; _DOMImageElement.style.visibility = "hidden"; + if ([CPPlatform supportsDragAndDrop]) + { + _DOMImageElement.setAttribute("draggable", "true"); + _DOMImageElement.style["-khtml-user-drag"] = "element"; + } #endif self = [super initWithCoder:aCoder]; diff --git a/AppKit/CPMenu.j b/AppKit/CPMenu.j index 35c39fa1b..70a6f39f9 100644 --- a/AppKit/CPMenu.j +++ b/AppKit/CPMenu.j @@ -672,7 +672,7 @@ var _CPMenuBarVisible = NO, [menuWindow setDelegate:self]; [menuWindow setBackgroundStyle:isForMenuBar ? _CPMenuWindowMenuBarBackgroundStyle : _CPMenuWindowPopUpBackgroundStyle]; - [menuWindow setFrameOrigin:[[anEvent window] convertBaseToBridge:[anEvent locationInWindow]]]; + [menuWindow setFrameOrigin:[[anEvent window] convertBaseToGlobal:[anEvent locationInWindow]]]; [menuWindow orderFront:self]; [menuWindow beginTrackingWithEvent:anEvent sessionDelegate:self didEndSelector:@selector(_menuWindowDidFinishTracking:highlightedItem:)]; @@ -904,7 +904,7 @@ var STICKY_TIME_INTERVAL = 500, CPTimeInterval _startTime; int _scrollingState; - CGPoint _lastScreenLocation; + CGPoint _lastGlobalLocation; BOOL _isShowingTopScrollIndicator; BOOL _isShowingBottomScrollIndicator; @@ -921,10 +921,10 @@ var STICKY_TIME_INTERVAL = 500, menuWindow = _CPMenuWindowPool.pop(); else menuWindow = [[_CPMenuWindow alloc] init]; - + [menuWindow setFont:aFont]; [menuWindow setMenu:aMenu]; - + return menuWindow; } @@ -1076,35 +1076,42 @@ var STICKY_TIME_INTERVAL = 500, - (void)constrainToScreen { + // FIXME: There are integral window issues with platform windows. + // FIXME: This gets called far too often. _unconstrainedFrame = CGRectMakeCopy([self frame]); - var screenBounds = CGRectInset([[self platformWindow] contentBounds], 5.0, 5.0), - constrainedFrame = CGRectIntersection(_unconstrainedFrame, screenBounds), - menuViewOrigin = [self convertBaseToBridge:CGPointMake(LEFT_MARGIN, TOP_MARGIN)]; - + var isBrowser = [CPPlatform isBrowser], + visibleFrame = CGRectInset(isBrowser ? [[self platformWindow] contentBounds] : [[self screen] visibleFrame], 5.0, 5.0), + constrainedFrame = CGRectIntersection(_unconstrainedFrame, visibleFrame); + + // We don't want to simply intersect the visible frame and the unconstrained frame. + // We should be allowing as much of the width to fit as possible (pushing back and forward). constrainedFrame.origin.x = CGRectGetMinX(_unconstrainedFrame); constrainedFrame.size.width = CGRectGetWidth(_unconstrainedFrame); - - if (CGRectGetWidth(constrainedFrame) > CGRectGetWidth(screenBounds)) - constrainedFrame.size.width = CGRectGetWidth(screenBounds); - - if (CGRectGetMaxX(constrainedFrame) > CGRectGetMaxX(screenBounds)) - constrainedFrame.origin.x -= CGRectGetMaxX(constrainedFrame) - CGRectGetMaxX(screenBounds); - - if (CGRectGetMinX(constrainedFrame) < CGRectGetMinX(screenBounds)) - constrainedFrame.origin.x = CGRectGetMinX(screenBounds); - + + if (CGRectGetWidth(constrainedFrame) > CGRectGetWidth(visibleFrame)) + constrainedFrame.size.width = CGRectGetWidth(visibleFrame); + + if (CGRectGetMaxX(constrainedFrame) > CGRectGetMaxX(visibleFrame)) + constrainedFrame.origin.x -= CGRectGetMaxX(constrainedFrame) - CGRectGetMaxX(visibleFrame); + + if (CGRectGetMinX(constrainedFrame) < CGRectGetMinX(visibleFrame)) + constrainedFrame.origin.x = CGRectGetMinX(visibleFrame); + + // This needs to happen before changing the frame. + var menuViewOrigin = [self convertBaseToGlobal:CGPointMake(LEFT_MARGIN, TOP_MARGIN)]; + [super setFrame:constrainedFrame]; - - var topMargin = TOP_MARGIN, + + var moreAbove = menuViewOrigin.y < CGRectGetMinY(constrainedFrame) + TOP_MARGIN, + moreBelow = menuViewOrigin.y + CGRectGetHeight([_menuView frame]) > CGRectGetMaxY(constrainedFrame) - BOTTOM_MARGIN, + + topMargin = TOP_MARGIN, bottomMargin = BOTTOM_MARGIN, contentView = [self contentView], bounds = [contentView bounds]; - - var moreAbove = menuViewOrigin.y < CGRectGetMinY(constrainedFrame) + TOP_MARGIN, - moreBelow = menuViewOrigin.y + CGRectGetHeight([_menuView frame]) > CGRectGetMaxY(constrainedFrame) - BOTTOM_MARGIN; - + if (moreAbove) { topMargin += SCROLL_INDICATOR_HEIGHT; @@ -1113,9 +1120,9 @@ var STICKY_TIME_INTERVAL = 500, [_moreAboveView setFrameOrigin:CGPointMake((CGRectGetWidth(bounds) - CGRectGetWidth(frame)) / 2.0, (TOP_MARGIN + SCROLL_INDICATOR_HEIGHT - CGRectGetHeight(frame)) / 2.0)]; } - + [_moreAboveView setHidden:!moreAbove]; - + if (moreBelow) { bottomMargin += SCROLL_INDICATOR_HEIGHT; @@ -1124,13 +1131,13 @@ var STICKY_TIME_INTERVAL = 500, } [_moreBelowView setHidden:!moreBelow]; - + var clipFrame = CGRectMake(LEFT_MARGIN, topMargin, CGRectGetWidth(constrainedFrame) - LEFT_MARGIN - RIGHT_MARGIN, CGRectGetHeight(constrainedFrame) - topMargin - bottomMargin) - + [_menuClipView setFrame:clipFrame]; [_menuView setFrameSize:CGSizeMake(CGRectGetWidth(clipFrame), CGRectGetHeight([_menuView frame]))]; - - [_menuView scrollPoint:CGPointMake(0.0, [self convertBaseToBridge:clipFrame.origin].y - menuViewOrigin.y)]; + + [_menuView scrollPoint:CGPointMake(0.0, [self convertBaseToGlobal:clipFrame.origin].y - menuViewOrigin.y)]; } - (void)cancelTracking @@ -1154,11 +1161,11 @@ var STICKY_TIME_INTERVAL = 500, { var type = [anEvent type], theWindow = [anEvent window], - screenLocation = theWindow ? [theWindow convertBaseToBridge:[anEvent locationInWindow]] : [anEvent locationInWindow]; - - if (type == CPPeriodic) + globalLocation = theWindow ? [theWindow convertBaseToGlobal:[anEvent locationInWindow]] : [anEvent locationInWindow]; + + if (type === CPPeriodic) { - var constrainedBounds = CGRectInset([[self platformWindow] contentBounds], 5.0, 5.0); + var constrainedBounds = CGRectInset([CPPlatform isBrowser] ? [[self platformWindow] contentBounds] : [[self screen] visibleFrame], 5.0, 5.0); if (_scrollingState == _CPMenuWindowScrollingStateUp) { @@ -1172,13 +1179,13 @@ var STICKY_TIME_INTERVAL = 500, [self setFrame:_unconstrainedFrame]; [self constrainToScreen]; - screenLocation = _lastScreenLocation; + globalLocation = _lastGlobalLocation; } - _lastScreenLocation = screenLocation; + _lastGlobalLocation = globalLocation; var menu = [_menuView menu], - menuLocation = [self convertBridgeToBase:screenLocation], + menuLocation = [self convertGlobalToBase:globalLocation], activeItemIndex = [_menuView itemIndexAtPoint:[_menuView convertPoint:menuLocation fromView:nil]], mouseOverMenuView = [[menu itemAtIndex:activeItemIndex] view]; @@ -1209,7 +1216,7 @@ var STICKY_TIME_INTERVAL = 500, _lastMouseOverMenuView = nil; } - [menu _highlightItemAtIndex:[_menuView itemIndexAtPoint:[_menuView convertPoint:[self convertBridgeToBase:screenLocation] fromView:nil]]]; + [menu _highlightItemAtIndex:[_menuView itemIndexAtPoint:[_menuView convertPoint:[self convertGlobalToBase:globalLocation] fromView:nil]]]; if (type == CPMouseMoved || type == CPLeftMouseDragged || type == CPLeftMouseDown) { @@ -1219,11 +1226,11 @@ var STICKY_TIME_INTERVAL = 500, _scrollingState = _CPMenuWindowScrollingStateNone; // If we're at or above of the top scroll indicator... - if (screenLocation.y < CGRectGetMinY(frame) + TOP_MARGIN + SCROLL_INDICATOR_HEIGHT) + if (globalLocation.y < CGRectGetMinY(frame) + TOP_MARGIN + SCROLL_INDICATOR_HEIGHT) _scrollingState = _CPMenuWindowScrollingStateUp; // If we're at or below the bottom scroll indicator... - else if (screenLocation.y > CGRectGetMaxY(frame) - BOTTOM_MARGIN - SCROLL_INDICATOR_HEIGHT) + else if (globalLocation.y > CGRectGetMaxY(frame) - BOTTOM_MARGIN - SCROLL_INDICATOR_HEIGHT) _scrollingState = _CPMenuWindowScrollingStateDown; if (_scrollingState != oldScrollingState) @@ -1447,10 +1454,12 @@ var _CPMenuBarWindowBackgroundColor = nil, - (id)init { - var platformWindowWidth = CGRectGetWidth([[CPPlatformWindow primaryPlatformWindow] contentBounds]); - - self = [super initWithContentRect:CGRectMake(0.0, 0.0, platformWindowWidth, MENUBAR_HEIGHT) styleMask:CPBorderlessWindowMask]; - + var contentRect = [CPPlatform isBrowser] ? [[CPPlatformWindow primaryPlatformWindow] contentBounds] : [[self screen] visibleFrame]; + + contentRect.size.height = MENUBAR_HEIGHT; + + self = [super initWithContentRect:contentRect styleMask:CPBorderlessWindowMask]; + if (self) { // FIXME: http://280north.lighthouseapp.com/projects/13294-cappuccino/tickets/39-dont-allow-windows-to-go-above-menubar diff --git a/AppKit/CPPasteboard.j b/AppKit/CPPasteboard.j index f74711361..4da0d92ec 100644 --- a/AppKit/CPPasteboard.j +++ b/AppKit/CPPasteboard.j @@ -25,6 +25,8 @@ @import @import +#include "Platform/Platform.h" + CPGeneralPboard = @"CPGeneralPboard"; CPFontPboard = @"CPFontPboard"; @@ -213,7 +215,7 @@ var CPPasteboards = nil; */ - (CPString)availableTypeFromArray:(CPArray)anArray { - return [_types firstObjectCommonWithArray:anArray]; + return [[self types] firstObjectCommonWithArray:anArray]; } /*! @@ -304,3 +306,70 @@ var CPPasteboards = nil; } @end + +#if PLATFORM(DOM) + +var DOMDataTransferPasteboard = nil; + +@implementation _CPDOMDataTransferPasteboard : CPPasteboard +{ + DataTransfer _dataTransfer; +} + ++ (_CPDOMDataTransferPasteboard)DOMDataTransferPasteboard +{ + if (!DOMDataTransferPasteboard) + DOMDataTransferPasteboard = [[_CPDOMDataTransferPasteboard alloc] init]; + + return DOMDataTransferPasteboard; +} + +- (void)_setDataTransfer:(DataTransfer)aDataTransfer +{ + _dataTransfer = aDataTransfer; +} + +- (void)_setPasteboard:(CPPasteboard)aPasteboard +{ + _dataTransfer.clearData(); + + var types = [aPasteboard types], + count = types.length; + + while (count--) + { + var type = types[count]; + + if (type === CPStringPboardType) + _dataTransfer.setData(type, [aPasteboard stringForType:type]); + else + _dataTransfer.setData(type, [[aPasteboard dataForType:type] string]); + } +} + +- (CPArray)types +{ + return Array.prototype.slice.apply(_dataTransfer.types); +} + +- (CPData)dataForType:(CPString)aType +{ + var dataString = _dataTransfer.getData(aType); + + if (aType === CPStringPboardType) + return [CPData dataFromPropertyList:dataString format:kCFPropertyList280NorthFormat_v1_0 errorDescription:0]; + + return [CPData dataWithString:dataString]; +} + +- (id)propertyListForType:(CPString)aType +{ + if (aType === CPStringPboardType) + return _dataTransfer.getData(aType); + + return [CPPropertyListSerialization propertyListFromData:[self dataForType:aType] format:CPPropertyListUnknownFormat errorDescription:nil]; +} + +@end + +#endif diff --git a/AppKit/CPPopUpButton.j b/AppKit/CPPopUpButton.j index b3776fd77..17700fb28 100644 --- a/AppKit/CPPopUpButton.j +++ b/AppKit/CPPopUpButton.j @@ -650,7 +650,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down"); // Pull Down Menus show up directly below their buttons. if ([self pullsDown]) - var menuOrigin = [theWindow convertBaseToBridge:[self convertPoint:CGPointMake(0.0, CGRectGetMaxY([self bounds])) toView:nil]]; + var menuOrigin = [theWindow convertBaseToGlobal:[self convertPoint:CGPointMake(0.0, CGRectGetMaxY([self bounds])) toView:nil]]; // Pop Up Menus attempt to show up "on top" of the selected item. else @@ -661,21 +661,21 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down"); // 2. Move LEFT by whatever indentation we have (offsetWidths, aka, window margin, item margin, etc). // 3. MOVE UP by the difference in sizes of the content and menu item, this will only work if the content is vertically centered. var contentRect = [self convertRect:[self contentRectForBounds:[self bounds]] toView:nil], - menuOrigin = [theWindow convertBaseToBridge:contentRect.origin], + menuOrigin = [theWindow convertBaseToGlobal:contentRect.origin], menuItemRect = [menuWindow rectForItemAtIndex:_selectedIndex]; menuOrigin.x -= CGRectGetMinX(menuItemRect) + [menuWindow overlapOffsetWidth] + [[[menu itemAtIndex:_selectedIndex] _menuItemView] overlapOffsetWidth]; menuOrigin.y -= CGRectGetMinY(menuItemRect) + (CGRectGetHeight(menuItemRect) - CGRectGetHeight(contentRect)) / 2.0; } - + [menuWindow setFrameOrigin:menuOrigin]; - + var menuMaxX = CGRectGetMaxX([menuWindow frame]), - buttonMaxX = [theWindow convertBaseToBridge:CGPointMake(CGRectGetMaxX([self convertRect:[self bounds] toView:nil]), 0.0)].x; - + buttonMaxX = [theWindow convertBaseToGlobal:CGPointMake(CGRectGetMaxX([self convertRect:[self bounds] toView:nil]), 0.0)].x; + if (menuMaxX < buttonMaxX) [menuWindow setMinWidth:CGRectGetWidth([menuWindow frame]) + buttonMaxX - menuMaxX - ([self pullsDown] ? 0.0 : VISIBLE_MARGIN)]; - + [menuWindow orderFront:self]; [menuWindow beginTrackingWithEvent:anEvent sessionDelegate:self didEndSelector:@selector(menuWindowDidFinishTracking:highlightedItem:)]; } diff --git a/AppKit/CPScreen.j b/AppKit/CPScreen.j new file mode 100644 index 000000000..4d0b7b3c8 --- /dev/null +++ b/AppKit/CPScreen.j @@ -0,0 +1,16 @@ + +@import + + +#import "CoreGraphics/CGGeometry.h" + +@implementation CPScreen : CPObject +{ +} + +- (CGRect)visibleFrame +{ + return _CGRectMake(window.screen.availLeft, window.screen.availTop, window.screen.availWidth, window.screen.availHeight); +} + +@end \ No newline at end of file diff --git a/AppKit/CPSplitView.j b/AppKit/CPSplitView.j index 97622b881..366a2682c 100644 --- a/AppKit/CPSplitView.j +++ b/AppKit/CPSplitView.j @@ -423,7 +423,7 @@ var CPSplitViewHorizontalImage = nil, frameA = [viewA frame], viewB = _subviews[dividerIndex + 1], frameB = [viewB frame]; - + var realPosition = MAX(MIN(position, actualMax), actualMin); if (position < proposedMin + (actualMin - proposedMin) / 2) @@ -488,8 +488,9 @@ var CPSplitViewHorizontalImage = nil, totalSizableSpace = 0; var nonSizableSpace = totalSizableSpace ? bounds.size[_sizeComponent] - totalSizableSpace : 0, - ratio = (bounds.size[_sizeComponent] - totalDividers*dividerThickness - nonSizableSpace) / (oldSize[_sizeComponent]- totalDividers*dividerThickness - nonSizableSpace), - remainingFlexibleSpace = bounds.size[_sizeComponent] - oldSize[_sizeComponent]; + remainingFlexibleSpace = bounds.size[_sizeComponent] - oldSize[_sizeComponent], + oldDimension = (oldSize[_sizeComponent]- totalDividers*dividerThickness - nonSizableSpace), + ratio = oldDimension <= 0 ? 0 : (bounds.size[_sizeComponent] - totalDividers*dividerThickness - nonSizableSpace) / oldDimension; for (index = 0; index < count; ++index) { @@ -510,7 +511,7 @@ var CPSplitViewHorizontalImage = nil, viewFrame.size[_sizeComponent] = [view frame].size[_sizeComponent]; else alert("SHOULD NEVER GET HERE"); - + bounds.origin[_originComponent] += viewFrame.size[_sizeComponent] + dividerThickness; [view setFrame:viewFrame]; diff --git a/AppKit/CPView.j b/AppKit/CPView.j index 9d0d78bc9..e2ca68020 100644 --- a/AppKit/CPView.j +++ b/AppKit/CPView.j @@ -274,7 +274,7 @@ var CPViewFlags = { }, #if PLATFORM(DOM) _DOMElement = DOMElementPrototype.cloneNode(false); - + CPDOMDisplayServerSetStyleLeftTop(_DOMElement, NULL, _CGRectGetMinX(aFrame), _CGRectGetMinY(aFrame)); CPDOMDisplayServerSetStyleSize(_DOMElement, width, height); diff --git a/AppKit/CPWindow/CPWindow.j b/AppKit/CPWindow/CPWindow.j index c8b7612f2..e851f38ba 100644 --- a/AppKit/CPWindow/CPWindow.j +++ b/AppKit/CPWindow/CPWindow.j @@ -27,6 +27,7 @@ @import "CGGeometry.j" @import "CPAnimation.j" @import "CPResponder.j" +@import "CPScreen.j" @import "CPPlatformWindow.j" #include "../Platform/Platform.h" @@ -96,61 +97,61 @@ CPBackgroundWindowLevel = -1; @group CPWindowLevel @global */ -CPNormalWindowLevel = 4; +CPNormalWindowLevel = 0; /* Floating palette type window @group CPWindowLevel @global */ -CPFloatingWindowLevel = 5; +CPFloatingWindowLevel = 3; /* Submenu type window @group CPWindowLevel @global */ -CPSubmenuWindowLevel = 6; +CPSubmenuWindowLevel = 3; /* For a torn-off menu @group CPWindowLevel @global */ -CPTornOffMenuWindowLevel = 6; +CPTornOffMenuWindowLevel = 3; /* For the application's main menu @group CPWindowLevel @global */ -CPMainMenuWindowLevel = 8; +CPMainMenuWindowLevel = 24; /* Status window level @group CPWindowLevel @global */ -CPStatusWindowLevel = 9; +CPStatusWindowLevel = 25; /* Level for a modal panel @group CPWindowLevel @global */ -CPModalPanelWindowLevel = 10; +CPModalPanelWindowLevel = 8; /* Level for a pop up menu @group CPWindowLevel @global */ -CPPopUpMenuWindowLevel = 11; +CPPopUpMenuWindowLevel = 101; /* Level for a window being dragged @group CPWindowLevel @global */ -CPDraggingWindowLevel = 12; +CPDraggingWindowLevel = 500; /* Level for the screens saver @group CPWindowLevel @global */ -CPScreenSaverWindowLevel = 13; +CPScreenSaverWindowLevel = 1000; /* The receiver is removed from the screen list and hidden. @@ -288,6 +289,8 @@ var CPWindowSaveImage = nil, BOOL _autorecalculatesKeyViewLoop; BOOL _keyViewLoopIsDirty; + BOOL _sharesChromeWithPlatformWindow; + // Bridge Support #if PLATFORM(DOM) DOMElement _DOMElement; @@ -336,7 +339,19 @@ CPTexturedBackgroundWindowMask if (self) { - [self setPlatformWindow:[CPPlatformWindow primaryPlatformWindow]]; + var windowViewClass = [[self class] _windowViewClassForStyleMask:aStyleMask]; + + _frame = [windowViewClass frameRectForContentRect:aContentRect]; + + [self _setSharesChromeWithPlatformWindow:![CPPlatform isBrowser]]; + + if ([CPPlatform isBrowser]) + [self setPlatformWindow:[CPPlatformWindow primaryPlatformWindow]]; + else + { + [self setPlatformWindow:[[CPPlatformWindow alloc] initWithContentRect:_frame]]; + [self platformWindow]._only = self; + } _isFullPlatformWindow = NO; _registeredDraggedTypes = [CPSet set]; @@ -347,15 +362,13 @@ CPTexturedBackgroundWindowMask CPApp._windows[_windowNumber] = self; _styleMask = aStyleMask; - _level = CPNormalWindowLevel; - + + [self setLevel:CPNormalWindowLevel]; + _minSize = CGSizeMake(0.0, 0.0); _maxSize = CGSizeMake(1000000.0, 1000000.0); // Create our border view which is the actual root of our view hierarchy. - var windowViewClass = [[self class] _windowViewClassForStyleMask:aStyleMask]; - - _frame = [windowViewClass frameRectForContentRect:aContentRect]; _windowView = [[windowViewClass alloc] initWithFrame:CGRectMake(0.0, 0.0, CGRectGetWidth(_frame), CGRectGetHeight(_frame)) styleMask:aStyleMask]; [_windowView _setWindow:self]; @@ -375,9 +388,12 @@ CPTexturedBackgroundWindowMask _DOMElement.style.visibility = "visible"; _DOMElement.style.zIndex = 0; - CPDOMDisplayServerSetStyleLeftTop(_DOMElement, NULL, _CGRectGetMinX(_frame), _CGRectGetMinY(_frame)); + if (![self _sharesChromeWithPlatformWindow]) + { + CPDOMDisplayServerSetStyleLeftTop(_DOMElement, NULL, _CGRectGetMinX(_frame), _CGRectGetMinY(_frame)); + } + CPDOMDisplayServerSetStyleSize(_DOMElement, 1, 1); - CPDOMDisplayServerAppendChild(_DOMElement, _windowView._DOMElement); #endif @@ -442,22 +458,25 @@ CPTexturedBackgroundWindowMask _windowView = aWindowView; -#if PLATFORM(DOM) if (oldWindowView) { [oldWindowView _setWindow:nil]; [oldWindowView noteToolbarChanged]; +#if PLATFORM(DOM) CPDOMDisplayServerRemoveChild(_DOMElement, oldWindowView._DOMElement); +#endif } if (_windowView) { +#if PLATFORM(DOM) CPDOMDisplayServerAppendChild(_DOMElement, _windowView._DOMElement); +#endif var contentRect = [_contentView convertRect:[_contentView bounds] toView:nil]; - contentRect.origin = [self convertBaseToBridge:contentRect.origin]; + contentRect.origin = [self convertBaseToGlobal:contentRect.origin]; [_windowView _setWindow:self]; [_windowView setNextResponder:self]; @@ -467,7 +486,6 @@ CPTexturedBackgroundWindowMask [self setFrame:[self frameRectForContentRect:contentRect]]; } -#endif } - (void)setFullPlatformWindow:(BOOL)shouldBeFullPlatformWindow @@ -494,7 +512,7 @@ CPTexturedBackgroundWindowMask [self setLevel:CPBackgroundWindowLevel]; [self setHasShadow:NO]; [self setAutoresizingMask:CPWindowWidthSizable | CPWindowHeightSizable]; - [self setFrame:[_platformWindow usableContentFrame]]; + [self setFrame:[_platformWindow visibleFrame]]; } else { @@ -598,16 +616,22 @@ CPTexturedBackgroundWindowMask - (void)setFrameOrigin:(CGPoint)anOrigin { var origin = _frame.origin; - + if (_CGPointEqualToPoint(origin, anOrigin)) return; - + origin.x = anOrigin.x; origin.y = anOrigin.y; + if ([self _sharesChromeWithPlatformWindow]) + [_platformWindow setContentOrigin:origin]; + + else + { #if PLATFORM(DOM) - CPDOMDisplayServerSetStyleLeftTop(_DOMElement, NULL, origin.x, origin.y); + CPDOMDisplayServerSetStyleLeftTop(_DOMElement, NULL, origin.x, origin.y); #endif + } [[CPNotificationCenter defaultCenter] postNotificationName:CPWindowDidMoveNotification object:self]; } @@ -627,9 +651,12 @@ CPTexturedBackgroundWindowMask [_windowView setFrameSize:aSize]; + if ([self _sharesChromeWithPlatformWindow]) + [_platformWindow setContentSize:aSize]; + if (_hasShadow) [_shadowView setFrameSize:_CGSizeMake(SHADOW_MARGIN_LEFT + aSize.width + SHADOW_MARGIN_RIGHT, SHADOW_MARGIN_BOTTOM + aSize.height + SHADOW_MARGIN_TOP + SHADOW_DISTANCE)]; - + if (!_isAnimating && [_delegate respondsToSelector:@selector(windowDidResize:)]) [_delegate windowDidResize:self]; } @@ -671,6 +698,9 @@ CPTexturedBackgroundWindowMask CPApp._keyWindow = nil; } + + if ([self _sharesChromeWithPlatformWindow]) + [_platformWindow orderOut:self]; } /*! @@ -690,6 +720,9 @@ CPTexturedBackgroundWindowMask - (void)setLevel:(int)aLevel { _level = aLevel; + + if ([self _sharesChromeWithPlatformWindow]) + [_platformWindow setLevel:aLevel]; } /*! @@ -881,9 +914,12 @@ CPTexturedBackgroundWindowMask { if (_hasShadow === shouldHaveShadow) return; - + _hasShadow = shouldHaveShadow; - + + if ([self _sharesChromeWithPlatformWindow]) + return [_platformWindow setHasShadow:shouldHaveShadow]; + if (_hasShadow) { var bounds = [_windowView bounds]; @@ -1120,6 +1156,11 @@ CPTexturedBackgroundWindowMask return _representedURL; } +- (CPScreen)screen +{ + return [[CPScreen alloc] init]; +} + // Moving /*! @@ -1175,7 +1216,7 @@ CPTexturedBackgroundWindowMask return; case CPLeftMouseDown: _leftMouseDownView = [_windowView hitTest:point]; - + if (_leftMouseDownView != _firstResponder && [_leftMouseDownView acceptsFirstResponder]) [self makeFirstResponder:_leftMouseDownView]; @@ -1343,7 +1384,7 @@ CPTexturedBackgroundWindowMask */ - (void)dragImage:(CPImage)anImage at:(CGPoint)imageLocation offset:(CGSize)mouseOffset event:(CPEvent)anEvent pasteboard:(CPPasteboard)aPasteboard source:(id)aSourceObject slideBack:(BOOL)slideBack { - [[CPDragServer sharedDragServer] dragImage:anImage fromWindow:self at:[self convertBaseToBridge:imageLocation] offset:mouseOffset event:anEvent pasteboard:aPasteboard source:aSourceObject slideBack:slideBack]; + [[CPDragServer sharedDragServer] dragImage:anImage fromWindow:self at:[self convertBaseToGlobal:imageLocation] offset:mouseOffset event:anEvent pasteboard:aPasteboard source:aSourceObject slideBack:slideBack]; } - (void)_noteRegisteredDraggedTypes:(CPSet)pasteboardTypes @@ -1378,9 +1419,9 @@ CPTexturedBackgroundWindowMask @param aSourceObject the drag operation controller @param slideBack Whether the view should 'slide back' if the drag is rejected */ -- (void)dragView:(CPView)aView at:(CGPoint)imageLocation offset:(CGSize)mouseOffset event:(CPEvent)anEvent pasteboard:(CPPasteboard)aPasteboard source:(id)aSourceObject slideBack:(BOOL)slideBack +- (void)dragView:(CPView)aView at:(CGPoint)viewLocation offset:(CGSize)mouseOffset event:(CPEvent)anEvent pasteboard:(CPPasteboard)aPasteboard source:(id)aSourceObject slideBack:(BOOL)slideBack { - [[CPDragServer sharedDragServer] dragView:aView fromWindow:self at:[self convertBaseToBridge:imageLocation] offset:mouseOffset event:anEvent pasteboard:aPasteboard source:aSourceObject slideBack:slideBack]; + [[CPDragServer sharedDragServer] dragView:aView fromWindow:self at:[self convertBaseToGlobal:viewLocation] offset:mouseOffset event:anEvent pasteboard:aPasteboard source:aSourceObject slideBack:slideBack]; } /*! @@ -1632,7 +1673,7 @@ CPTexturedBackgroundWindowMask [_windowView noteToolbarChanged]; if (_isFullPlatformWindow) - newFrame = [_platformWindow usableContentFrame]; + newFrame = [_platformWindow visibleFrame]; else { newFrame = CGRectMakeCopy([self frame]); @@ -1926,7 +1967,7 @@ var keyViewComparator = function(a, b, context) - (void)resizeWithOldPlatformWindowSize:(CGSize)aSize { if ([self isFullPlatformWindow]) - return [self setFrame:[_platformWindow usableContentFrame]]; + return [self setFrame:[_platformWindow visibleFrame]]; if (_autoresizingMask == CPWindowNotSizable) return; @@ -1967,24 +2008,58 @@ var keyViewComparator = function(a, b, context) return _autoresizingMask; } -/* - @ignore -*/ -- (CGPoint)convertBaseToBridge:(CGPoint)aPoint +- (CGPoint)convertBaseToGlobal:(CGPoint)aPoint { - var origin = [self frame].origin; - - return CGPointMake(aPoint.x + origin.x, aPoint.y + origin.y); + return [CPPlatform isBrowser] ? [self convertBaseToPlatformWindow:aPoint] : [self convertBaseToScreen:aPoint]; } -/* - @ignore -*/ -- (CGPoint)convertBridgeToBase:(CGPoint)aPoint +- (CGPoint)convertGlobalToBase:(CGPoint)aPoint { + return [CPPlatform isBrowser] ? [self convertPlatformWindowToBase:aPoint] : [self convertScreenToBase:aPoint]; +} + +- (CGPoint)convertBaseToPlatformWindow:(CGPoint)aPoint +{ + if ([self _sharesChromeWithPlatformWindow]) + return aPoint; + var origin = [self frame].origin; - - return CGPointMake(aPoint.x - origin.x, aPoint.y - origin.y); + + return _CGPointMake(aPoint.x + origin.x, aPoint.y + origin.y); +} + +- (CGPoint)convertPlatformWindowToBase:(CGPoint)aPoint +{ + if ([self _sharesChromeWithPlatformWindow]) + return aPoint; + + var origin = [self frame].origin; + + return _CGPointMake(aPoint.x - origin.x, aPoint.y - origin.y); +} + +- (CGPoint)convertScreenToBase:(CGPoint)aPoint +{ + return [self convertPlatformWindowToBase:[_platformWindow convertScreenToBase:aPoint]]; +} + +- (CGPoint)convertBaseToScreen:(CGPoint)aPoint +{ + return [_platformWindow convertBaseToScreen:[self convertBaseToPlatformWindow:aPoint]]; +} + +- (void)_setSharesChromeWithPlatformWindow:(BOOL)shouldShareFrameWithPlatformWindow +{ + // We canna' do it captain! We just don't have the power! + if (shouldShareFrameWithPlatformWindow && [CPPlatform isBrowser]) + return; + + _sharesChromeWithPlatformWindow = shouldShareFrameWithPlatformWindow; +} + +- (BOOL)_sharesChromeWithPlatformWindow +{ + return _sharesChromeWithPlatformWindow; } // Undo and Redo Support @@ -2039,6 +2114,22 @@ var keyViewComparator = function(a, b, context) return [self isFullPlatformWindow]; } +/* + @ignore +*/ +- (CGPoint)convertBaseToBridge:(CGPoint)aPoint +{ + return [self convertBaseToPlatformWindow:aPoint]; +} + +/* + @ignore +*/ +- (CGPoint)convertBridgeToBase:(CGPoint)aPoint +{ + return [self convertPlatformWindowToBase:aPoint]; +} + @end var interpolate = function(fromValue, toValue, progress) diff --git a/AppKit/CPWindow/_CPWindowView.j b/AppKit/CPWindow/_CPWindowView.j index fe2d1ca4d..890044daa 100644 --- a/AppKit/CPWindow/_CPWindowView.j +++ b/AppKit/CPWindow/_CPWindowView.j @@ -100,7 +100,7 @@ var _CPWindowViewResizeIndicatorImage = nil; - (void)mouseDown:(CPEvent)anEvent { var theWindow = [self window]; - + if ((_styleMask & CPResizableWindowMask) && _resizeIndicator) { // FIXME: This should be better @@ -142,10 +142,14 @@ var _CPWindowViewResizeIndicatorImage = nil; - (CGPoint)_pointWithinScreenFrame:(CGPoint)aPoint { + // FIXME: this is WRONG, all of this is WRONG + if (![CPPlatform isBrowser]) + return aPoint; + var visibleFrame = _cachedScreenFrame; if (!visibleFrame) - visibleFrame = [[CPPlatformWindow primaryPlatformWindow] usableContentFrame]; + visibleFrame = [[CPPlatformWindow primaryPlatformWindow] visibleFrame]; var restrictedPoint = CGPointMake(0, 0); @@ -158,22 +162,24 @@ var _CPWindowViewResizeIndicatorImage = nil; - (void)trackMoveWithEvent:(CPEvent)anEvent { var type = [anEvent type]; - + if (type === CPLeftMouseUp) { _cachedScreenFrame = nil; return; } + else if (type === CPLeftMouseDown) { - _mouseDraggedPoint = [[self window] convertBaseToBridge:[anEvent locationInWindow]]; - _cachedScreenFrame = [[CPPlatformWindow primaryPlatformWindow] usableContentFrame]; + _mouseDraggedPoint = [[self window] convertBaseToGlobal:[anEvent locationInWindow]]; + _cachedScreenFrame = [[CPPlatformWindow primaryPlatformWindow] visibleFrame]; } + else if (type === CPLeftMouseDragged) { var theWindow = [self window], frame = [theWindow frame], - location = [theWindow convertBaseToBridge:[anEvent locationInWindow]], + location = [theWindow convertBaseToGlobal:[anEvent locationInWindow]], origin = [self _pointWithinScreenFrame:CGPointMake(_CGRectGetMinX(frame) + (location.x - _mouseDraggedPoint.x), _CGRectGetMinY(frame) + (location.y - _mouseDraggedPoint.y))]; @@ -322,7 +328,7 @@ var _CPWindowViewResizeIndicatorImage = nil; { var contentRect = [self convertRect:[[theWindow contentView] frame] toView:nil]; - contentRect.origin = [theWindow convertBaseToBridge:contentRect.origin]; + contentRect.origin = [theWindow convertBaseToGlobal:contentRect.origin]; [self setAutoresizesSubviews:NO]; [theWindow setFrame:[theWindow frameRectForContentRect:contentRect]]; diff --git a/AppKit/Cib/_CPCibCustomView.j b/AppKit/Cib/_CPCibCustomView.j index c420a90d4..808cf85fc 100644 --- a/AppKit/Cib/_CPCibCustomView.j +++ b/AppKit/Cib/_CPCibCustomView.j @@ -71,7 +71,7 @@ var _CPCibCustomViewClassNameKey = @"_CPCibCustomViewClassNameKey"; - (id)_cibInstantiate { var theClass = CPClassFromString(_className); - + // If we don't have this class, just use CPView. // FIXME: Should we instead throw an exception? if (!theClass) diff --git a/AppKit/Platform/CPPlatform.j b/AppKit/Platform/CPPlatform.j index 8a75b53ab..0e92269e9 100644 --- a/AppKit/Platform/CPPlatform.j +++ b/AppKit/Platform/CPPlatform.j @@ -24,4 +24,14 @@ [CPPlatformWindow setPrimaryPlatformWindow:[[CPPlatformWindow alloc] _init]]; } ++ (BOOL)isBrowser +{ + return typeof window.cpIsDesktop === "undefined"; +} + ++ (BOOL)supportsDragAndDrop +{ + return CPFeatureIsCompatible(CPHTMLDragAndDropFeature); +} + @end diff --git a/AppKit/Platform/CPPlatformWindow.j b/AppKit/Platform/CPPlatformWindow.j index 8a6bd2ea5..c8450d9dc 100644 --- a/AppKit/Platform/CPPlatformWindow.j +++ b/AppKit/Platform/CPPlatformWindow.j @@ -9,7 +9,10 @@ var PrimaryPlatformWindow = NULL; @implementation CPPlatformWindow : CPObject { - CGRect _contentRect; + CGRect _contentRect; + + CPInteger _level; + BOOL _hasShadow; #if PLATFORM(DOM) DOMWindow _DOMWindow; @@ -86,7 +89,7 @@ var PrimaryPlatformWindow = NULL; return contentBounds; } -- (void)usableContentFrame +- (CGRect)visibleFrame { var frame = [self contentBounds]; @@ -103,6 +106,11 @@ var PrimaryPlatformWindow = NULL; return frame; } +- (void)usableContentFrame +{ + return [self visibleFrame]; +} + - (void)setContentRect:(CGRect)aRect { if (!aRect || _CGRectEqualToRect(_contentRect, aRect)) @@ -144,30 +152,53 @@ var PrimaryPlatformWindow = NULL; { [self setContentRect:[self nativeContentRect]]; } -/* -- (BOOL)isVisible + +- (CGPoint)convertBaseToScreen:(CGPoint)aPoint { - return NO; + var contentRect = [self contentRect]; + + return _CGPointMake(aPoint.x + _CGRectGetMinX(contentRect), aPoint.y + _CGRectGetMinY(contentRect)); } -/* -+ (BOOL)supportsMultipleWindows +- (CGPoint)convertScreenToBase:(CGPoint)aPoint { -#if PLATFORM(BROWSER) - return YES; + var contentRect = [self contentRect]; + + return _CGPointMake(aPoint.x - _CGRectGetMinX(contentRect), aPoint.y - _CGRectGetMinY(contentRect)); +} + +- (BOOL)isVisible +{ +#if PLATFORM(DOM) + return _DOMWindow !== NULL; #else return NO; #endif } -*/ + +- (void)setLevel:(CPInteger)aLevel +{ + _level = aLevel; + +#if PLATFORM(DOM) + if (_DOMWindow && _DOMWindow.cpSetLevel) + _DOMWindow.cpSetLevel(aLevel); +#endif +} + +- (void)setHasShadow:(BOOL)shouldHaveShadow +{ + _hasShadow = shouldHaveShadow; + +#if PLATFORM(DOM) + if (_DOMWindow && _DOMWindow.cpSetHasShadow) + _DOMWindow.cpSetHasShadow(shouldHaveShadow); +#endif +} - (BOOL)supportsFullPlatformWindows { -#if PLATFORM(BROWSER) - return YES; -#else - return NO; -#endif + return [CPPlatform isBrowser]; } @end diff --git a/AppKit/Platform/DOM/CPPlatformWindow+DOM.j b/AppKit/Platform/DOM/CPPlatformWindow+DOM.j index c491a9a2a..07dceed0f 100644 --- a/AppKit/Platform/DOM/CPPlatformWindow+DOM.j +++ b/AppKit/Platform/DOM/CPPlatformWindow+DOM.j @@ -81,13 +81,13 @@ var CTRL_KEY_CODE = 17; _DOMWindow = window; _contentRect = _CGRectMakeZero(); + _windowLevels = []; + _windowLayers = [CPDictionary dictionary]; + [self registerDOMWindow]; [self updateFromNativeContentRect]; _charCodes = {}; - - _windowLevels = []; - _windowLayers = [CPDictionary dictionary]; } return self; @@ -98,6 +98,9 @@ var CTRL_KEY_CODE = 17; if (!_DOMWindow) return [self contentRect]; + if (_DOMWindow.cpFrame) + return _DOMWindow.cpFrame(); + var contentRect = _CGRectMakeZero(); if (window.screenTop) @@ -126,6 +129,9 @@ var CTRL_KEY_CODE = 17; if (!_DOMWindow) return; + if (_DOMWindow.cpSetFrame) + return _DOMWindow.cpSetFrame([self contentRect]); + var origin = [self contentRect].origin, nativeOrigin = [self nativeContentRect].origin; @@ -137,6 +143,9 @@ var CTRL_KEY_CODE = 17; if (!_DOMWindow) return; + if (_DOMWindow.cpSetFrame) + return _DOMWindow.cpSetFrame([self contentRect]); + var size = [self contentRect].size, nativeSize = [self nativeContentRect].size; @@ -155,6 +164,10 @@ var CTRL_KEY_CODE = 17; _DOMBodyElement = theDocument.getElementsByTagName("body")[0]; + // FIXME: Always do this? + if ([CPPlatform supportsDragAndDrop]) + _DOMBodyElement.style["-khtml-user-select"] = "none"; + _DOMBodyElement.webkitTouchCallout = "none"; _DOMFocusElement = theDocument.createElement("input"); @@ -180,6 +193,9 @@ var CTRL_KEY_CODE = 17; var theClass = [self class], + dragEventImplementation = class_getMethodImplementation(theClass, @selector(dragEvent:)), + dragEventCallback = function (anEvent) { dragEventImplementation(self, nil, anEvent); }, + resizeEventSelector = @selector(resizeEvent:), resizeEventImplementation = class_getMethodImplementation(theClass, resizeEventSelector), resizeEventCallback = function (anEvent) { resizeEventImplementation(self, nil, anEvent); }, @@ -202,6 +218,16 @@ var CTRL_KEY_CODE = 17; if (theDocument.addEventListener) { + if ([CPPlatform supportsDragAndDrop]) + { + theDocument.addEventListener("dragstart", dragEventCallback, NO); + theDocument.addEventListener("drag", dragEventCallback, NO); + theDocument.addEventListener("dragend", dragEventCallback, NO); + theDocument.addEventListener("dragover", dragEventCallback, NO); + theDocument.addEventListener("dragleave", dragEventCallback, NO); + theDocument.addEventListener("drop", dragEventCallback, NO); + } + theDocument.addEventListener("mouseup", mouseEventCallback, NO); theDocument.addEventListener("mousedown", mouseEventCallback, NO); theDocument.addEventListener("mousemove", mouseEventCallback, NO); @@ -220,7 +246,7 @@ var CTRL_KEY_CODE = 17; _DOMWindow.addEventListener("resize", resizeEventCallback, NO); - _DOMWindow.addEventListener("beforeunload", function() + _DOMWindow.addEventListener("unload", function() { [self updateFromNativeContentRect]; @@ -294,26 +320,106 @@ var CTRL_KEY_CODE = 17; } } -- (BOOL)isVisible -{ - return _DOMWindow !== NULL; -} - - (void)orderFront:(id)aSender { if (_DOMWindow) return _DOMWindow.focus(); - _DOMWindow = window.open("", "", "menubar=no,location=no,resizable=yes,scrollbars=no,status=no,left=" + _CGRectGetMinX(_contentRect) + ",top=" + _CGRectGetMinY(_contentRect) + ",width=" + _CGRectGetWidth(_contentRect) + ",height=" + _CGRectGetHeight(_contentRect)); + _DOMWindow = window.open("", "_blank", "menubar=no,location=no,resizable=yes,scrollbars=no,status=no,left=" + _CGRectGetMinX(_contentRect) + ",top=" + _CGRectGetMinY(_contentRect) + ",width=" + _CGRectGetWidth(_contentRect) + ",height=" + _CGRectGetHeight(_contentRect)); + + // FIXME: cpSetFrame? + _DOMWindow.document.write(""); + _DOMWindow.document.close(); + + if (![CPPlatform isBrowser]) + { + _DOMWindow.cpSetLevel(_level); + _DOMWindow.cpSetHasShadow(_hasShadow); + } [self registerDOMWindow]; } - (void)orderOut:(id)aSender { + if (!_DOMWindow) + return; + _DOMWindow.close(); } +- (void)dragEvent:(DOMEvent)aDOMEvent +{ + var type = aDOMEvent.type, + dragServer = [CPDragServer sharedDragServer], + location = _CGPointMake(aDOMEvent.clientX, aDOMEvent.clientY), + pasteboard = [_CPDOMDataTransferPasteboard DOMDataTransferPasteboard]; + + [pasteboard _setDataTransfer:aDOMEvent.dataTransfer]; + + if (aDOMEvent.type === "dragstart") + { + [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode]; + + [pasteboard _setPasteboard:[dragServer draggingPasteboard]]; + + var draggedWindow = [dragServer draggedWindow], + draggedWindowFrame = [draggedWindow frame], + DOMDragElement = draggedWindow._DOMElement; + + DOMDragElement.style.left = -_CGRectGetWidth(draggedWindowFrame) + "px"; + DOMDragElement.style.top = -_CGRectGetHeight(draggedWindowFrame) + "px"; + + document.getElementsByTagName("body")[0].appendChild(DOMDragElement); + + var draggingOffset = [dragServer draggingOffset]; + + aDOMEvent.dataTransfer.setDragImage(DOMDragElement, draggingOffset.width, draggingOffset.height); + + [dragServer draggingStartedInPlatformWindow:self location:[CPPlatform isBrowser] ? location : _CGPointMake(aDOMEvent.screenX, aDOMEvent.screenY)]; + } + + else if (type === "drag") + [dragServer draggingSourceUpdatedWithLocation:[CPPlatform isBrowser] ? location : _CGPointMake(aDOMEvent.screenX, aDOMEvent.screenY)]; + + else if (type === "dragover" || type === "dragleave") + { + if (aDOMEvent.preventDefault) + aDOMEvent.preventDefault(); + + var dropEffect = "none", + dragOperation = [dragServer draggingUpdatedInPlatformWindow:self location:location]; + + if (dragOperation === CPDragOperationMove || dragOperation === CPDragOperationGeneric || dragOperation === CPDragOperationPrivate) + dropEffect = "move"; + + else if (dragOperation === CPDragOperationCopy) + dropEffect = "copy"; + + else if (dragOperation === CPDragOperationLink) + dropEffect = "link"; + + aDOMEvent.dataTransfer.dropEffect = dropEffect; + } + + else if (type === "dragend") + [dragServer draggingEndedInPlatformWindow:self]; + + else //if (type === "drop") + { + [dragServer performDragOperationInPlatformWindow:self]; + + // W3C Model + if (aDOMEvent.preventDefault) + aDOMEvent.preventDefault(); + + if (aDOMEvent.stopPropagation) + aDOMEvent.stopPropagation(); + } + + [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode]; +} + - (void)keyEvent:(DOMEvent)aDOMEvent { var event, @@ -616,7 +722,7 @@ var CTRL_KEY_CODE = 17; var type = _overriddenEventType || aDOMEvent.type; // IE's event order is down, up, up, dblclick, so we have create these events artificially. - if (type === CPDOMEventDoubleClick) + if (type === @"dblclick") { _overriddenEventType = CPDOMEventMouseDown; [self _bridgeMouseEvent:aDOMEvent]; @@ -655,7 +761,7 @@ var CTRL_KEY_CODE = 17; } if (windowNumber) - location = [CPApp._windows[windowNumber] convertBridgeToBase:location]; + location = [CPApp._windows[windowNumber] convertPlatformWindowToBase:location]; if (type === "mouseup") { @@ -676,9 +782,15 @@ var CTRL_KEY_CODE = 17; } else if (type === "mousedown") - { + { if (ExcludedDOMElements[sourceElement.tagName] && sourceElement != _DOMFocusElement) { + if ([CPPlatform supportsDragAndDrop]) + { + _DOMBodyElement.setAttribute("draggable", "false"); + _DOMBodyElement.style["-khtml-user-drag"] = "none"; + } + _DOMEventMode = YES; _mouseIsDown = YES; @@ -693,6 +805,11 @@ var CTRL_KEY_CODE = 17; return; } + else if ([CPPlatform supportsDragAndDrop]) + { + _DOMBodyElement.setAttribute("draggable", "true"); + _DOMBodyElement.style["-khtml-user-drag"] = "element"; + } event = _CPEventFromNativeMouseEvent(aDOMEvent, CPLeftMouseDown, location, modifierFlags, timestamp, windowNumber, nil, -1, CPDOMEventGetClickCount(_lastMouseDown, timestamp, location), 0); @@ -700,7 +817,7 @@ var CTRL_KEY_CODE = 17; _lastMouseDown = event; } - else // if (type === "mousemove") + else // if (type === "mousemove" || type === "drag") { if (_DOMEventMode) return; @@ -715,7 +832,7 @@ var CTRL_KEY_CODE = 17; [CPApp sendEvent:event]; } - if (StopDOMEventPropagation) + if (StopDOMEventPropagation && (![CPPlatform supportsDragAndDrop] || type !== "mousedown" && ![[CPDragServer sharedDragServer] isDragging])) CPDOMEventStop(aDOMEvent, self); [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode]; @@ -801,7 +918,10 @@ var CTRL_KEY_CODE = 17; while (windowCount--) { var theWindow = windows[windowCount]; - + + if ([theWindow _sharesChromeWithPlatformWindow]) + return [theWindow _dragHitTest:aPoint pasteboard:aPasteboard]; + if ([theWindow containsPoint:aPoint]) return [theWindow _dragHitTest:aPoint pasteboard:aPasteboard]; } @@ -817,7 +937,7 @@ var CTRL_KEY_CODE = 17; } - (CPWindow)hitTest:(CPPoint)location -{ +{if (self._only) return self._only; var levels = _windowLevels, layers = _windowLayers, levelCount = levels.length, diff --git a/AppKit/_CPImageAndTextView.j b/AppKit/_CPImageAndTextView.j index 8710d269f..c80fed2e7 100644 --- a/AppKit/_CPImageAndTextView.j +++ b/AppKit/_CPImageAndTextView.j @@ -511,7 +511,13 @@ var HORIZONTAL_MARGIN = 3.0, else { _DOMImageElement = document.createElement("img"); - + + if ([CPPlatform supportsDragAndDrop]) + { + _DOMImageElement.setAttribute("draggable", "true"); + _DOMImageElement.style["-khtml-user-drag"] = "element"; + } + var imageStyle = _DOMImageElement.style; imageStyle.top = "0px"; diff --git a/External/jack b/External/jack index a93518cd1..92ffbf823 160000 --- a/External/jack +++ b/External/jack @@ -1 +1 @@ -Subproject commit a93518cd13bd0a92286b25cdb38806f7bbc883c7 +Subproject commit 92ffbf823d3fed38c4004b0a98136d7ea414ac8e diff --git a/External/narwhal b/External/narwhal index 6ce4d9288..c8601619a 160000 --- a/External/narwhal +++ b/External/narwhal @@ -1 +1 @@ -Subproject commit 6ce4d928875cc4252885fec6725524bfa9855b19 +Subproject commit c8601619a8835b4570609b2cff00a001c5329f73 diff --git a/Foundation/CPPropertyListSerialization.j b/Foundation/CPPropertyListSerialization.j index 19c71fa5c..342a55257 100644 --- a/Foundation/CPPropertyListSerialization.j +++ b/Foundation/CPPropertyListSerialization.j @@ -23,6 +23,7 @@ @import "CPObject.j" +CPPropertyListUnknownFormat = 0; CPPropertyListOpenStepFormat = kCFPropertyListOpenStepFormat; CPPropertyListXMLFormat_v1_0 = kCFPropertyListXMLFormat_v1_0; CPPropertyListBinaryFormat_v1_0 = kCFPropertyListBinaryFormat_v1_0; diff --git a/Objective-J/Tools/objj/lib-js/objj/objj.js b/Objective-J/Tools/objj/lib-js/objj/objj.js index 3d17a562a..f4ef4d678 100644 --- a/Objective-J/Tools/objj/lib-js/objj/objj.js +++ b/Objective-J/Tools/objj/lib-js/objj/objj.js @@ -1,4 +1,6 @@ -var File = require("file"); +var File = require("file"), + readline = require("readline").readline; + var window = require("browser/window"); // variables to be exported from the module, for use in objjc, etc @@ -67,7 +69,7 @@ exports.run = function(args) try { system.stdout.write("objj> ").flush(); - var input = system.stdin.readLine(), + var input = readline(), result = objj_eval(input); if (result !== undefined)