diff --git a/Headers/AppKit/NSView.h b/Headers/AppKit/NSView.h index 589deef46..941639789 100644 --- a/Headers/AppKit/NSView.h +++ b/Headers/AppKit/NSView.h @@ -36,10 +36,11 @@ #include #include -@class NSString; @class NSArray; -@class NSMutableArray; +@class NSAttributedString; @class NSData; +@class NSMutableArray; +@class NSString; @class NSWindow; @class NSPasteboard; @@ -243,6 +244,9 @@ typedef enum _NSFocusRingType { - (BOOL) lockFocusIfCanDraw; - (void) lockFocusInRect: (NSRect)rect; #endif +#if OS_API_VERSION(MAC_OS_X_VERSION_10_4, GS_API_LATEST) +- (BOOL) lockFocusIfCanDrawInContext: (NSGraphicsContext *)context; +#endif /* * Displaying @@ -258,7 +262,7 @@ typedef enum _NSFocusRingType { - (void) setNeedsDisplay: (BOOL)flag; - (void) setNeedsDisplayInRect: (NSRect)invalidRect; - (BOOL) isOpaque; -#if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST) +#if OS_API_VERSION(MAC_OS_X_VERSION_10_3, GS_API_LATEST) + (NSFocusRingType) defaultFocusRingType; - (void) setKeyboardFocusRingNeedsDisplayInRect: (NSRect)rect; - (void) setFocusRingType: (NSFocusRingType)focusRingType; @@ -276,7 +280,7 @@ typedef enum _NSFocusRingType { - (NSRect) visibleRect; - (BOOL) canDraw; - (BOOL) shouldDrawColor; -#if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST) +#if OS_API_VERSION(MAC_OS_X_VERSION_10_3, GS_API_LATEST) - (BOOL) wantsDefaultClipping; - (BOOL) needsToDrawRect: (NSRect)aRect; - (void) getRectsBeingDrawn: (const NSRect **)rects count: (int *)count; @@ -288,6 +292,12 @@ typedef enum _NSFocusRingType { - (void) viewWillStartLiveResize; - (void) viewDidEndLiveResize; #endif +#if OS_API_VERSION(MAC_OS_X_VERSION_10_4, GS_API_LATEST) +- (BOOL) preservesContentDuringLiveResize; +- (void) getRectsExposedDuringLiveResize: (NSRect[4])exposedRects count: (int *)count; +- (NSRect) rectPreservedDuringLiveResize; +#endif + /* * Graphics State Objects @@ -325,7 +335,7 @@ typedef enum _NSFocusRingType { - (void) registerForDraggedTypes: (NSArray*)newTypes; - (void) unregisterDraggedTypes; - (BOOL) shouldDelayWindowOrderingForEvent: (NSEvent*)anEvent; -#if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST) +#if OS_API_VERSION(MAC_OS_X_VERSION_10_2, GS_API_LATEST) - (BOOL) dragPromisedFilesOfTypes: (NSArray *)typeArray fromRect: (NSRect)aRect source: (id)sourceObject @@ -441,7 +451,7 @@ typedef enum _NSFocusRingType { - (void) setPreviousKeyView: (NSView*)aView; - (NSView*) previousKeyView; - (NSView*) previousValidKeyView; -#if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST) +#if OS_API_VERSION(MAC_OS_X_VERSION_10_3, GS_API_LATEST) - (BOOL) canBecomeKeyView; #endif @@ -514,6 +524,10 @@ typedef enum _NSFocusRingType { atPlacement:(NSPoint)location; - (void)endDocument; #endif +#if OS_API_VERSION(MAC_OS_X_VERSION_10_4, GS_API_LATEST) +- (NSAttributedString *)pageFooter; +- (NSAttributedString *)pageHeader; +#endif @end diff --git a/Headers/AppKit/NSWindow.h b/Headers/AppKit/NSWindow.h index f651c218d..78fb056b6 100644 --- a/Headers/AppKit/NSWindow.h +++ b/Headers/AppKit/NSWindow.h @@ -444,6 +444,10 @@ APPKIT_EXPORT NSSize NSTokenSize; - (void) setBackingType: (NSBackingStoreType)type; - (BOOL) isOneShot; - (void) setOneShot: (BOOL)flag; +#if OS_API_VERSION(MAC_OS_X_VERSION_10_4, GS_API_LATEST) +- (NSGraphicsContext*) graphicsContext; +#endif + /* * Screens and window depths diff --git a/Source/NSBox.m b/Source/NSBox.m index 037fe6bbb..eab3bfe4f 100644 --- a/Source/NSBox.m +++ b/Source/NSBox.m @@ -67,8 +67,13 @@ // - (id) initWithFrame: (NSRect)frameRect { - [super initWithFrame: frameRect]; + NSView *cv; + + self = [super initWithFrame: frameRect]; + if (!self) + return self; + _cell = [[NSCell alloc] initTextCell: @"Title"]; [_cell setAlignment: NSCenterTextAlignment]; [_cell setBordered: NO]; @@ -80,10 +85,10 @@ _title_position = NSAtTop; _title_rect = NSZeroRect; [self setAutoresizesSubviews: NO]; - _content_view = [NSView new]; - [super addSubview: _content_view]; - [_content_view setFrame: [self calcSizesAllowingNegative: NO]]; - RELEASE(_content_view); + + cv = [NSView new]; + [self setContentView: cv]; + RELEASE(cv); return self; } diff --git a/Source/NSView.m b/Source/NSView.m index 3ed1a9930..95aa6640d 100644 --- a/Source/NSView.m +++ b/Source/NSView.m @@ -244,7 +244,7 @@ GSSetDragTypes(NSView* obj, NSArray *types) } } } - [self releaseGState]; + [self renewGState]; } } @@ -427,7 +427,9 @@ GSSetDragTypes(NSView* obj, NSArray *types) - (id) initWithFrame: (NSRect)frameRect { - [super init]; + self = [super init]; + if (!self) + return self; if (frameRect.size.width < 0) { @@ -443,7 +445,7 @@ GSSetDragTypes(NSView* obj, NSArray *types) _bounds.origin = NSZeroPoint; // Set bounds rectangle _bounds.size = _frame.size; - _boundsMatrix = [NSAffineTransform new]; // Map fromsuperview to bounds + _boundsMatrix = [NSAffineTransform new]; // Map from superview to bounds _matrixToWindow = [NSAffineTransform new]; // Map to window coordinates _matrixFromWindow = [NSAffineTransform new]; // Map from window coordinates @@ -451,18 +453,20 @@ GSSetDragTypes(NSView* obj, NSArray *types) _tracking_rects = [NSMutableArray new]; _cursor_rects = [NSMutableArray new]; - _super_view = nil; - _window = nil; - _is_rotated_from_base = NO; - _is_rotated_or_scaled_from_base = NO; + // Some values are already set by initialisation + //_super_view = nil; + //_window = nil; + //_is_rotated_from_base = NO; + //_is_rotated_or_scaled_from_base = NO; _rFlags.needs_display = YES; - _post_frame_changes = NO; + //_post_frame_changes = NO; _autoresizes_subviews = YES; _autoresizingMask = NSViewNotSizable; - _coordinates_valid = NO; - _nextKeyView = 0; - _previousKeyView = 0; + //_coordinates_valid = NO; + //_nextKeyView = 0; + //_previousKeyView = 0; + // cache as optimization _rFlags.flipped_view = [self isFlipped]; return self; @@ -507,7 +511,7 @@ GSSetDragTypes(NSView* obj, NSArray *types) /* * Now we clean up the previous view array, in case subclasses have - * overridden the default -setNextkeyView: method and broken things. + * overridden the default -setNextKeyView: method and broken things. * We also relase the memory we used. */ if (pKV(self) != 0) @@ -596,34 +600,9 @@ GSSetDragTypes(NSView* obj, NSArray *types) */ - (void) addSubview: (NSView*)aView { - if (aView == nil) - { - [NSException raise: NSInvalidArgumentException - format: @"Adding a nil subview"]; - } - if ([self isDescendantOf: aView]) - { - [NSException raise: NSInvalidArgumentException - format: @"addSubview: creates a loop in the views tree!"]; - } - - RETAIN(aView); - [aView removeFromSuperview]; - if (aView->_coordinates_valid) - { - (*invalidateImp)(aView, invalidateSel); - } - [aView viewWillMoveToWindow: _window]; - [aView viewWillMoveToSuperview: self]; - [aView setNextResponder: self]; - [_sub_views addObject: aView]; - _rFlags.has_subviews = 1; - [aView resetCursorRects]; - [aView setNeedsDisplay: YES]; - [aView _viewDidMoveToWindow]; - [aView viewDidMoveToSuperview]; - [self didAddSubview: aView]; - RELEASE(aView); + [self addSubview: aView + positioned: NSWindowAbove + relativeTo: nil]; } - (void) addSubview: (NSView*)aView @@ -647,7 +626,26 @@ GSSetDragTypes(NSView* obj, NSArray *types) if (aView == otherView) return; - index = [_sub_views indexOfObjectIdenticalTo: otherView]; + RETAIN(aView); + [aView removeFromSuperview]; + if (aView->_coordinates_valid) + { + (*invalidateImp)(aView, invalidateSel); + } + [aView viewWillMoveToWindow: _window]; + [aView viewWillMoveToSuperview: self]; + [aView setNextResponder: self]; + + // Do this after the removeFromSuperview, as aView may already + // be a subview and the index could change. + if (otherView == nil) + { + index = NSNotFound; + } + else + { + index = [_sub_views indexOfObjectIdenticalTo: otherView]; + } if (index == NSNotFound) { if (place == NSWindowBelow) @@ -660,15 +658,6 @@ GSSetDragTypes(NSView* obj, NSArray *types) index += 1; } - RETAIN(aView); - [aView removeFromSuperview]; - if (aView->_coordinates_valid) - { - (*invalidateImp)(aView, invalidateSel); - } - [aView viewWillMoveToWindow: _window]; - [aView viewWillMoveToSuperview: self]; - [aView setNextResponder: self]; [_sub_views insertObject: aView atIndex: index]; _rFlags.has_subviews = 1; [aView resetCursorRects]; @@ -790,7 +779,7 @@ GSSetDragTypes(NSView* obj, NSArray *types) * which assumes the view is still in the view hierarchy */ for (view = [_window firstResponder]; - view != nil && [view respondsToSelector:@selector(superview)]; + view != nil && [view respondsToSelector: @selector(superview)]; view = [view superview]) { if (view == aView) @@ -1720,21 +1709,20 @@ static NSRect convert_rect_using_matrices(NSRect aRect, NSAffineTransform *matri */ - (void) allocateGState { + // FIXME: This should create an actual gState _allocate_gstate = 1; _renew_gstate = 1; } /** - Frees the gstate object, if there is one. Note that the next time - the view is lockFocused, the gstate will be allocated again. */ + Frees the gstate object, if there is one. +*/ - (void) releaseGState { if (_allocate_gstate && _gstate) GSUndefineGState(GSCurrentContext(), _gstate); _gstate = 0; - /* Note that the next time we lock focus, we'll realloc a gstate (if - _allocate_gstate). This seems to make sense, and also allows us - to call this method each time we invalidate the coordinates */ + _allocate_gstate = 0; } /** @@ -1742,7 +1730,10 @@ static NSRect convert_rect_using_matrices(NSRect aRect, NSAffineTransform *matri which is used to encapsulate drawing information about the view. Most of the time a gstate object is created from scratch when the view is focused, so if the view is not currently focused or - allocateGState has not been called, then this method will */ + allocateGState has not been called, then this method will return 0. + FIXME: The above is what the OpenStep and Cocoa specification say, but + gState is 0 unless allocateGState has been called. +*/ - (int) gState { return _gstate; @@ -1754,6 +1745,9 @@ static NSRect convert_rect_using_matrices(NSRect aRect, NSAffineTransform *matri - (void) renewGState { _renew_gstate = 1; + /* Note that the next time we lock focus, we'll realloc a gstate (if + _allocate_gstate). This seems to make sense, and also allows us + to call this method each time we invalidate the coordinates */ } /* Overridden by subclasses to setup custom gstate */ @@ -1761,9 +1755,8 @@ static NSRect convert_rect_using_matrices(NSRect aRect, NSAffineTransform *matri { } -- (void) lockFocusInRect: (NSRect)rect +- (void) _lockFocusInContext: ctxt inRect: (NSRect)rect { - NSGraphicsContext *ctxt = GSCurrentContext(); NSRect wrect; int window_gstate = 0; @@ -1777,6 +1770,8 @@ static NSRect convert_rect_using_matrices(NSRect aRect, NSAffineTransform *matri } } + // FIXME: Set current context? + [ctxt lockFocusView: self inRect: rect]; wrect = [self convertRect: rect toView: nil]; NSDebugLLog(@"NSView", @"-lockFocusInRect: %@\n" @@ -1807,8 +1802,6 @@ static NSRect convert_rect_using_matrices(NSRect aRect, NSAffineTransform *matri { [[self _matrixToWindow] concat]; } - DPSrectclip(ctxt, NSMinX(rect), NSMinY(rect), - NSWidth(rect), NSHeight(rect)); /* Allow subclases to make other modifications */ [self setUpGState]; @@ -1848,14 +1841,20 @@ static NSRect convert_rect_using_matrices(NSRect aRect, NSAffineTransform *matri } } + } + + if ([self wantsDefaultClipping]) + { /* Clip to the visible rectangle - which will never be greater * than the bounds of the view. This prevents drawing outside * our bounds */ DPSrectclip(ctxt, NSMinX(rect), NSMinY(rect), - NSWidth(rect), NSHeight(rect)); + NSWidth(rect), NSHeight(rect)); } - /* This is obsolete. Backends shouldn't depend on this */ + + /* Tell backends that images are drawn upside down. + This is needed when a backend is able to handle full image transformation. */ GSWSetViewIsFlipped(ctxt, _rFlags.flipped_view); } @@ -1899,6 +1898,11 @@ static NSRect convert_rect_using_matrices(NSRect aRect, NSAffineTransform *matri [ctxt unlockFocusView: self needsFlush: YES ]; } +- (void) lockFocusInRect: (NSRect)rect +{ + [self _lockFocusInContext: [_window graphicsContext] inRect: rect]; +} + - (void) lockFocus { [self lockFocusInRect: [self visibleRect]]; @@ -1910,10 +1914,15 @@ static NSRect convert_rect_using_matrices(NSRect aRect, NSAffineTransform *matri } - (BOOL) lockFocusIfCanDraw +{ + return [self lockFocusIfCanDrawInContext: [_window graphicsContext]]; +} + +- (BOOL) lockFocusIfCanDrawInContext: (NSGraphicsContext *)context; { if ([self canDraw]) { - [self lockFocus]; + [self _lockFocusInContext: context inRect: [self visibleRect]]; return YES; } else @@ -1923,7 +1932,7 @@ static NSRect convert_rect_using_matrices(NSRect aRect, NSAffineTransform *matri } - (BOOL) canDraw -{ // not implemented per OS spec FIX ME +{ if (((viewIsPrinting != nil) && [self isDescendantOf: viewIsPrinting]) || ((_window != nil) && ([_window windowNumber] != 0) && ![self isHiddenOrHasHiddenAncestor])) @@ -2200,6 +2209,7 @@ static NSRect convert_rect_using_matrices(NSRect aRect, NSAffineTransform *matri */ [self lockFocusInRect: aRect]; [self drawRect: aRect]; + [self unlockFocusNeedsFlush: YES]; } if (_rFlags.has_subviews == YES) @@ -2266,11 +2276,6 @@ static NSRect convert_rect_using_matrices(NSRect aRect, NSAffineTransform *matri } } - if (NSIsEmptyRect(aRect) == NO) - { - [self unlockFocusNeedsFlush: YES]; - } - /* * If the rect we displayed contains the _invalidRect or _visibleRect * then we can empty _invalidRect. If all subviews have been @@ -2326,21 +2331,36 @@ static NSRect convert_rect_using_matrices(NSRect aRect, NSAffineTransform *matri - (BOOL) needsToDrawRect: (NSRect)aRect { - NSRect rect; - struct NSWindow_struct *window_t; + const NSRect *rects; + int i, count; - aRect = [self convertRect: aRect toView: nil]; - window_t = (struct NSWindow_struct *)_window; - rect = [[window_t->_rectsBeingDrawn lastObject] rectValue]; - return NSIntersectsRect(rect, aRect); + [self getRectsBeingDrawn: &rects count: &count]; + for (i = 0; i < count; i++) + { + if (NSIntersectsRect(aRect, rects[i])) + return YES; + } + return NO; } - (void) getRectsBeingDrawn: (const NSRect **)rects count: (int *)count { // FIXME + static NSRect rect; + struct NSWindow_struct *window_t; + + window_t = (struct NSWindow_struct *)_window; + rect = [[window_t->_rectsBeingDrawn lastObject] rectValue]; + rect = [self convertRect: rect fromView: nil]; + + if (rects != NULL) + { + *rects = ▭ + } + if (count != NULL) { - *count = 0; + *count = 1; } } @@ -2519,6 +2539,26 @@ in the main thread. _in_live_resize = NO; } +- (BOOL) preservesContentDuringLiveResize +{ + return NO; +} + +- (void) getRectsExposedDuringLiveResize: (NSRect[4])exposedRects count: (int *)count +{ + // FIXME + if (count != NULL) + { + *count = 1; + } + exposedRects[0] = _bounds; +} + +- (NSRect) rectPreservedDuringLiveResize +{ + return NSZeroRect; +} + /* * Scrolling */ @@ -2546,19 +2586,42 @@ in the main thread. } - (void) reflectScrolledClipView: (NSClipView*)aClipView -{} +{ +} - (void) scrollClipView: (NSClipView*)aClipView toPoint: (NSPoint)aPoint -{} +{ + [aClipView scrollToPoint: aPoint]; +} + +- (NSClipView*) _enclosingClipView +{ + static Class clipViewClass; + id aView = [self superview]; + + if (!clipViewClass) + { + clipViewClass = [NSClipView class]; + } + + while (aView != nil) + { + if ([aView isKindOfClass: clipViewClass]) + { + break; + } + aView = [aView superview]; + } + + return aView; +} - (void) scrollPoint: (NSPoint)aPoint { - NSClipView *s = (NSClipView*)_super_view; + NSClipView *s = [self _enclosingClipView]; - while (s != nil && [s isKindOfClass: [NSClipView class]] == NO) - { - s = (NSClipView*)[s superview]; - } + if (s == nil) + return; aPoint = [self convertPoint: aPoint toView: s]; if (NSEqualPoints(aPoint, [s bounds].origin) == NO) @@ -2567,8 +2630,20 @@ in the main thread. } } +/** + Copy on scroll method, should be called from [NSClipView setBoundsOrigin]. + */ - (void) scrollRect: (NSRect)aRect by: (NSSize)delta -{} +{ + NSPoint destPoint = aRect.origin; + + destPoint.x -= delta.width; + destPoint.y -= delta.height; + + [self lockFocus]; + NSCopyBits(0, aRect, destPoint); + [self unlockFocus]; +} /** Scrolls the nearest enclosing clip view the minimum required distance @@ -2577,12 +2652,8 @@ Returns YES iff any scrolling was done. */ - (BOOL) scrollRectToVisible: (NSRect)aRect { - NSClipView *s = (NSClipView*)_super_view; + NSClipView *s = [self _enclosingClipView]; - while (s != nil && [s isKindOfClass: [NSClipView class]] == NO) - { - s = (NSClipView*)[s superview]; - } if (s != nil) { NSRect vRect = [self visibleRect]; @@ -2621,11 +2692,17 @@ Returns YES iff any scrolling was done. - (NSScrollView*) enclosingScrollView { + static Class scrollViewClass; id aView = [self superview]; + if (!scrollViewClass) + { + scrollViewClass = [NSScrollView class]; + } + while (aView != nil) { - if ([aView isKindOfClass: [NSScrollView class]]) + if ([aView isKindOfClass: scrollViewClass]) { break; } @@ -2935,8 +3012,7 @@ static NSView* findByTag(NSView *view, int aTag, unsigned *level) - (BOOL) mouseDownCanMoveWindow { - // FIXME - return NO; + return ![self isOpaque]; } - (void) removeTrackingRect: (NSTrackingRectTag)tag @@ -3356,12 +3432,12 @@ static NSView* findByTag(NSView *view, int aTag, unsigned *level) _rFlags.has_draginfo = 1; if (_window != nil) { - - [GSDisplayServer addDragTypes: t toWindow: _window]; + // Remove the old types first, that way overlapping types stay assigned. if (o != nil) { [GSDisplayServer removeDragTypes: o fromWindow: _window]; } + [GSDisplayServer addDragTypes: t toWindow: _window]; } TEST_RELEASE(o); } @@ -3387,8 +3463,28 @@ static NSView* findByTag(NSView *view, int aTag, unsigned *level) slideBack: (BOOL)slideBack event: (NSEvent *)theEvent { - // FIXME - return NO; + // FIXME: Where to get the image from? + NSImage *anImage = nil; + NSPasteboard *pboard = [NSPasteboard pasteboardWithName: NSDragPboard]; + + if (anImage == nil) + return NO; + + [pboard declareTypes: [NSArray arrayWithObject: NSFilesPromisePboardType] + owner: sourceObject]; + // FIXME: Not sure if this is correct. + if (![pboard setPropertyList: typeArray + forType: NSFilesPromisePboardType]) + return NO; + + [self dragImage: anImage + at: aRect.origin + offset: NSMakeSize(0, 0) + event: theEvent + pasteboard: pboard + source: sourceObject + slideBack: slideBack]; + return YES; } /* @@ -3412,11 +3508,16 @@ static NSView* findByTag(NSView *view, int aTag, unsigned *level) { NSMutableData *data = [NSMutableData data]; - [[NSPrintOperation EPSOperationWithView: self - insideRect: aRect - toData: data] runOperation]; - - return data; + if ([[NSPrintOperation EPSOperationWithView: self + insideRect: aRect + toData: data] runOperation]) + { + return data; + } + else + { + return nil; + } } - (void) writeEPSInsideRect: (NSRect)rect @@ -3433,10 +3534,16 @@ static NSView* findByTag(NSView *view, int aTag, unsigned *level) { NSMutableData *data = [NSMutableData data]; - [[NSPrintOperation PDFOperationWithView: self - insideRect: aRect - toData: data] runOperation]; - return data; + if ([[NSPrintOperation PDFOperationWithView: self + insideRect: aRect + toData: data] runOperation]) + { + return data; + } + else + { + return nil; + } } - (void)writePDFInsideRect:(NSRect)aRect @@ -3773,6 +3880,8 @@ static NSView* findByTag(NSView *view, int aTag, unsigned *level) { DPSPrintf(ctxt, "__GSpagesaveobject restore\n\n"); } + + [self unlockFocus]; } - (void) endTrailer @@ -3781,6 +3890,23 @@ static NSView* findByTag(NSView *view, int aTag, unsigned *level) DPSPrintf(ctxt, "%%%%EOF\n"); } +- (NSAttributedString *) pageFooter +{ + return [[[NSAttributedString alloc] + initWithString: + [NSString stringWithFormat:@"Page %d", + [[NSPrintOperation currentOperation] currentPage]]] + autorelease]; +} + +- (NSAttributedString *) pageHeader +{ + return [[[NSAttributedString alloc] + initWithString: + [NSString stringWithFormat:@"%@ %@", [self printJobTitle], + [[NSCalendarDate calendarDate] description]]] autorelease]; +} + - (void) _loadPrinterProlog: (NSGraphicsContext *)ctxt { NSString *prolog; @@ -3874,10 +4000,13 @@ static NSView* findByTag(NSView *view, int aTag, unsigned *level) int nup; float scale; NSRect bounds; - NSGraphicsContext *ctxt = GSCurrentContext(); NSPrintOperation *printOp = [NSPrintOperation currentOperation]; + NSGraphicsContext *ctxt = [printOp context]; NSDictionary *dict = [[printOp printInfo] dictionary]; + // FIXME: Need to place this correctly + [self lockFocusIfCanDrawInContext: ctxt]; + if ([dict objectForKey: @"NSPrintPaperBounds"]) bounds = [[dict objectForKey: @"NSPrintPaperBounds"] rectValue]; else diff --git a/Source/NSWindow.m b/Source/NSWindow.m index 21f9fe454..71b0e19e6 100644 --- a/Source/NSWindow.m +++ b/Source/NSWindow.m @@ -1171,6 +1171,12 @@ many times. return [[self screen] deviceDescription]; } +- (NSGraphicsContext*) graphicsContext +{ + // FIXME + return GSCurrentContext(); +} + - (int) gState { if (_gstate <= 0)