This is NSView.m in view mode; [Download] [Up]
/* NSView.m The view class which encapsulates all drawing functionality Copyright (C) 1996 Free Software Foundation, Inc. Author: Scott Christley <scottc@net-community.com> Date: 1996 This file is part of the GNUstep GUI Library. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. If you are interested in a warranty or support for this source code, contact Scott Christley <scottc@net-community.com> for more information. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <gnustep/gui/NSView.h> #include <gnustep/gui/NSWindow.h> #include <gnustep/base/NSCoder.h> #include <gnustep/base/NSDictionary.h> #include <gnustep/base/NSThread.h> #include <gnustep/base/NSLock.h> // // Class variables // NSMutableDictionary *gnustep_gui_nsview_thread_dict; NSRecursiveLock *gnustep_gui_nsview_lock; // NSView notifications NSString *NSViewFrameChangedNotification; NSString *NSViewFocusChangedNotification; @implementation NSView // // Class methods // // // Initialization // + (void)initialize { if (self == [NSView class]) { NSLog(@"Initialize NSView class\n"); // Initial version [self setVersion:1]; // Allocate dictionary for maintaining // mapping of threads to focused views gnustep_gui_nsview_thread_dict = [NSMutableDictionary dictionary]; // Create lock for serializing access to dictionary gnustep_gui_nsview_lock = [[NSRecursiveLock alloc] init]; } } // // Focusing // // +++ Really each thread should have a stack! // + (void)pushFocusView:(NSView *)focusView { NSThread *current_thread = [NSThread currentThread]; // Obtain lock so we can edit the dictionary [gnustep_gui_nsview_lock lock]; // If no context then remove from dictionary if (!focusView) { [gnustep_gui_nsview_thread_dict removeObjectForKey: current_thread]; } else { [gnustep_gui_nsview_thread_dict setObject: focusView forKey: current_thread]; } [gnustep_gui_nsview_lock unlock]; } + (NSView *)popFocusView {} + (NSView *)focusView { NSThread *current_thread = [NSThread currentThread]; NSView *current_view = nil; // Get focused view for current thread [gnustep_gui_nsview_lock lock]; // current_view is nil if no focused view current_view = [gnustep_gui_nsview_thread_dict objectForKey: current_thread]; [gnustep_gui_nsview_lock unlock]; return current_view; } // // Instance methods // // // Initializing NSView Objects // - init { return [self initWithFrame:NSZeroRect]; } // The default initializer - (id)initWithFrame:(NSRect)frameRect { // Our super is NSResponder [super init]; // Set frame rectangle frame = frameRect; // Set bounds rectangle bounds.origin = NSZeroPoint; bounds.size = frame.size; // Initialize subview list sub_views = [NSMutableArray array]; // Initialize tracking rectangle list tracking_rects = [NSMutableArray array]; super_view = nil; window = nil; is_flipped = NO; is_rotated_from_base = NO; is_rotated_or_scaled_from_base = NO; opaque = NO; disable_autodisplay = NO; needs_display = YES; post_frame_changes = NO; autoresize_subviews = YES; return self; } - (void)dealloc { int i, j; //NSArray doesn't know -removeAllObjects yet //[sub_views removeAllObjects]; j = [sub_views count]; for (i = 0;i < j; ++i) [[sub_views objectAtIndex:i] release]; // no need -array is autoreleased //[sub_views release]; // Free the tracking rectangles j = [tracking_rects count]; for (i = 0;i < j; ++i) [[tracking_rects objectAtIndex:i] release]; [super dealloc]; } // // Managing the NSView Hierarchy // - (void)addSubview:(NSView *)aView { // Not a NSView --then forget it if (![aView isKindOfClass:[NSView class]]) { return; } // retain the object [aView retain]; // Add to our subview list [sub_views addObject:(id)aView]; [aView setSuperview:self]; [aView setNextResponder:self]; [aView viewWillMoveToWindow:window]; } - (void)addSubview:(NSView *)aView positioned:(NSWindowOrderingMode)place relativeTo:(NSView *)otherView { // Not a NSView --then forget it if (![aView isKindOfClass:[NSView class]]) return; // retain the object [aView retain]; // Add to our subview list [sub_views addObject:(id)aView]; [aView setSuperview:self]; // Make ourselves the next responder of the view [aView setNextResponder:self]; // Tell the view what window it has moved to [aView viewWillMoveToWindow:window]; } - (NSView *)ancestorSharedWithView:(NSView *)aView { NSView *v = nil; BOOL found = NO; return v; } - (BOOL)isDescendantOf:(NSView *)aView { int i, j; NSView *v; BOOL found = NO; // Not a NSView --then forget it if (![aView isKindOfClass:[NSView class]]) return NO; // Quick check if (aView == self) return YES; // No superview then this is end of the line if (!super_view) return NO; if (super_view == aView) return YES; return [super_view isDescendantOf:aView]; } - (NSView *)opaqueAncestor { return nil; } - (void)removeFromSuperview { int i, j; NSMutableArray *v; // No superview then just return if (!super_view) return; v = [super_view subviews]; j = [v count]; for (i = 0;i < j; ++i) { if ([v objectAtIndex:i] == self) [v removeObjectAtIndex:i]; } } - (void)replaceSubview:(NSView *)oldView with:(NSView *)newView { int i, j; NSView *v; // Not a NSView --then forget it if (![newView isKindOfClass:[NSView class]]) return; j = [sub_views count]; for (i = 0;i < j; ++i) { v = [sub_views objectAtIndex:i]; if (v == oldView) { // Found it then replace [sub_views replaceObjectAtIndex:i withObject:newView]; // release it as well [v release]; // and retain the new view [newView retain]; } else // Didn't find then pass down view hierarchy [v replaceSubview:oldView with:newView]; } } - (void)sortSubviewsUsingFunction:(int (*)(id ,id ,void *))compare context:(void *)context {} - (NSMutableArray *)subviews { return sub_views; } - (NSView *)superview { return super_view; } - (void)setSuperview:(NSView *)superview { // Not a NSView --then forget it if (![superview isKindOfClass:[NSView class]]) return; super_view = superview; } - (NSWindow *)window { // If we don't know our window then ask our super_view if (!window) window = [super_view window]; return window; } - (void)viewWillMoveToWindow:(NSWindow *)newWindow { int i, j; // not a window --then forget it // if (![newWindow isKindOfClass:[NSWindow class]]) return; window = newWindow; // Pass new window down to subviews j = [sub_views count]; for (i = 0;i < j; ++i) [[sub_views objectAtIndex:i] viewWillMoveToWindow:newWindow]; } // // Modifying the Frame Rectangle // - (float)frameRotation { return 0; } - (NSRect)frame { return frame; } - (void)rotateByAngle:(float)angle {} - (void)setFrame:(NSRect)frameRect { NSSize old_size = bounds.size; frame = frameRect; bounds.size = frame.size; // Resize subviews [self resizeSubviewsWithOldSize: old_size]; } - (void)setFrameOrigin:(NSPoint)newOrigin { frame.origin = newOrigin; } - (void)setFrameRotation:(float)angle {} - (void)setFrameSize:(NSSize)newSize { NSSize old_size = bounds.size; frame.size = newSize; bounds.size = newSize; // Resize subviews [self resizeSubviewsWithOldSize: old_size]; } // // Modifying the Coordinate System // - (float)boundsRotation { return 0; } - (NSRect)bounds { return bounds; } - (BOOL)isFlipped { return is_flipped; } - (BOOL)isRotatedFromBase { return is_rotated_from_base; } - (BOOL)isRotatedOrScaledFromBase { return is_rotated_or_scaled_from_base; } - (void)scaleUnitSquareToSize:(NSSize)newSize {} - (void)setBounds:(NSRect)aRect { bounds = aRect; } - (void)setBoundsOrigin:(NSPoint)newOrigin { bounds.origin = newOrigin; } - (void)setBoundsRotation:(float)angle {} - (void)setBoundsSize:(NSSize)newSize { bounds.size = newSize; } - (void)translateOriginToPoint:(NSPoint)point {} // // Converting Coordinates // - (NSRect)convertRectToWindow:(NSRect)r { NSRect f, t, a; id s; a = r; f = [self frame]; s = [self superview]; // climb up the superview chain while (s) { t = [s frame]; // translate frame f.origin.x += t.origin.x; f.origin.y += t.origin.y; s = [s superview]; } a.origin.x += f.origin.x; a.origin.y += f.origin.y; return a; } - (NSPoint)convertPointToWindow:(NSPoint)p { NSRect f, t; NSPoint a; id s; a = p; f = [self frame]; s = [self superview]; // climb up the superview chain while (s) { t = [s frame]; // translate frame f.origin.x += t.origin.x; f.origin.y += t.origin.y; s = [s superview]; } a.x += f.origin.x; a.y += f.origin.y; return a; } - (NSRect)centerScanRect:(NSRect)aRect { return NSZeroRect; } - (NSPoint)convertPoint:(NSPoint)aPoint fromView:(NSView *)aView { NSPoint p, q; NSRect r; // Must belong to the same window if (([self window] != [aView window]) && (aView)) return NSZeroPoint; // if aView is nil // then converting from window // so convert from the content from the content view of the window if (aView == nil) return [self convertPoint: aPoint fromView:[[self window] contentView]]; // Convert the point to window coordinates p = [aView convertPointToWindow: aPoint]; // Convert out origin to window coordinates q = [self convertPointToWindow: bounds.origin]; NSLog(@"point convert: %f %f %f %f\n", p.x, p.y, q.x, q.y); // now translate p.x -= q.x; p.y -= q.y; return p; } - (NSPoint)convertPoint:(NSPoint)aPoint toView:(NSView *)aView { NSPoint p, q; NSRect r; // Must belong to the same window if (([self window] != [aView window]) && (aView)) return NSZeroPoint; // if aView is nil // then converting to window if (aView == nil) return [self convertPointToWindow: aPoint]; // convert everything to window coordinates p = [self convertPointToWindow: aPoint]; r = [aView bounds]; q = [aView convertPointToWindow: r.origin]; NSLog(@"point convert: %f %f %f %f\n", p.x, p.y, q.x, q.y); // now translate p.x -= q.x; p.y -= q.y; return p; } - (NSRect)convertRect:(NSRect)aRect fromView:(NSView *)aView { NSRect r; // Must belong to the same window if (([self window] != [aView window]) && (aView)) return NSZeroRect; r = aRect; r.origin = [self convertPoint:r.origin fromView:aView]; r.size = [self convertSize:r.size fromView:aView]; return r; } - (NSRect)convertRect:(NSRect)aRect toView:(NSView *)aView { NSRect r; // Must belong to the same window if (([self window] != [aView window]) && (aView)) return NSZeroRect; r = aRect; r.origin = [self convertPoint:r.origin toView:aView]; r.size = [self convertSize:r.size toView:aView]; return r; } - (NSSize)convertSize:(NSSize)aSize fromView:(NSView *)aView { // Size would only change under scaling return aSize; } - (NSSize)convertSize:(NSSize)aSize toView:(NSView *)aView { // Size would only change under scaling return aSize; } // // Notifying Ancestor Views // - (BOOL)postsFrameChangedNotifications { return post_frame_changes; } - (void)setPostsFrameChangedNotifications:(BOOL)flag { post_frame_changes = flag; } // // Resizing Subviews // - (void)resizeSubviewsWithOldSize:(NSSize)oldSize { id e, o; // Are we suppose to resize our subviews? if (![self autoresizesSubviews]) return; e = [sub_views objectEnumerator]; o = [e nextObject]; while (o) { NSRect b = [o bounds]; NSSize old_size = b.size; // Resize the subview // Then tell it to resize its subviews [o resizeWithOldSuperviewSize: oldSize]; [o resizeSubviewsWithOldSize: old_size]; o = [e nextObject]; } } - (void)setAutoresizesSubviews:(BOOL)flag { autoresize_subviews = flag; } - (BOOL)autoresizesSubviews { return autoresize_subviews; } - (void)setAutoresizingMask:(unsigned int)mask {} - (unsigned int)autoresizingMask { return 0; } - (void)resizeWithOldSuperviewSize:(NSSize)oldSize {} // // Graphics State Objects // - (void)allocateGState {} - (void)releaseGState {} - (int)gState { return 0; } - (void)renewGState {} - (void)setUpGState {} // // Focusing // - (void)lockFocus { [[self class] pushFocusView: self]; } - (void)unlockFocus { [[self class] popFocusView]; } // // Displaying // - (BOOL)canDraw { return YES; } - (void)display { int i, j; [self lockFocus]; [self drawRect:bounds]; [self unlockFocus]; // Tell subviews to display j = [sub_views count]; for (i = 0;i < j; ++i) [(NSView *)[sub_views objectAtIndex:i] display]; } - (void)displayIfNeeded { if ((needs_display) && (opaque)) [self display]; } - (void)displayIfNeededIgnoringOpacity { if (needs_display) [self display]; } - (void)displayRect:(NSRect)aRect {} - (void)displayRectIgnoringOpacity:(NSRect)aRect {} - (void)drawRect:(NSRect)rect { NSColor *col; col = [window backgroundColor]; PSsetcolor(col); NSRectFill(rect); } - (NSRect)visibleRect { return bounds; } - (BOOL)isOpaque { return opaque; } - (BOOL)needsDisplay { return needs_display; } - (void)setNeedsDisplay:(BOOL)flag { needs_display = flag; } - (void)setNeedsDisplayInRect:(NSRect)invalidRect { needs_display = YES; } - (BOOL)shouldDrawColor { return YES; } // // Scrolling // - (NSRect)adjustScroll:(NSRect)newVisible { return NSZeroRect; } - (BOOL)autoscroll:(NSEvent *)theEvent { return NO; } - (void)reflectScrolledClipView:(NSClipView *)aClipView {} - (void)scrollClipView:(NSClipView *)aClipView toPoint:(NSPoint)aPoint {} - (void)scrollPoint:(NSPoint)aPoint {} - (void)scrollRect:(NSRect)aRect by:(NSSize)delta {} - (BOOL)scrollRectToVisible:(NSRect)aRect { return NO; } // // Managing the Cursor // - (void)addCursorRect:(NSRect)aRect cursor:(NSCursor *)anObject {} - (void)discardCursorRects {} - (void)removeCursorRect:(NSRect)aRect cursor:(NSCursor *)anObject {} - (void)resetCursorRects {} // // Assigning a Tag // - (int)tag { return -1; } - (id)viewWithTag:(int)aTag { int i, j; j = [sub_views count]; for (i = 0;i < j; ++i) { if ([[sub_views objectAtIndex:i] tag] == aTag) return [sub_views objectAtIndex:i]; } return nil; } // // Aiding Event Handling // - (BOOL)acceptsFirstMouse:(NSEvent *)theEvent { return NO; } - (NSView *)hitTest:(NSPoint)aPoint { NSPoint p; int i, j; NSView *v = nil, *w; // If not within our bounds then immediately return if (![self mouse:aPoint inRect:bounds]) return nil; // Check our sub_views j = [sub_views count]; for (i = 0;i < j; ++i) { w = [sub_views objectAtIndex:i]; p = [self convertPoint:aPoint toView:w]; v = [w hitTest:p]; if (v) break; } // It is either the subview or ourself if (v) { return v; } else { return self; } } - (BOOL)mouse:(NSPoint)aPoint inRect:(NSRect)aRect { if (aPoint.x < aRect.origin.x) return NO; if (aPoint.y < aRect.origin.y) return NO; if (aPoint.x > (aRect.origin.x + aRect.size.width)) return NO; if (aPoint.y > (aRect.origin.y + aRect.size.height)) return NO; return YES; } - (BOOL)performKeyEquivalent:(NSEvent *)theEvent { return NO; } - (void)removeTrackingRect:(NSTrackingRectTag)tag { int i, j; TrackingRectangle *m; j = [tracking_rects count]; for (i = 0;i < j; ++i) { m = (TrackingRectangle *)[tracking_rects objectAtIndex:i]; if ([m tag] == tag) { [m release]; [tracking_rects removeObjectAtIndex:i]; return; } } } - (BOOL)shouldDelayWindowOrderingForEvent:(NSEvent *)anEvent { return NO; } - (NSTrackingRectTag)addTrackingRect:(NSRect)aRect owner:(id)anObject userData:(void *)data assumeInside:(BOOL)flag { NSTrackingRectTag t; int i, j; TrackingRectangle *m; t = 0; j = [tracking_rects count]; for (i = 0;i < j; ++i) { m = (TrackingRectangle *)[tracking_rects objectAtIndex:i]; if ([m tag] > t) t = [m tag]; } ++t; m = [[TrackingRectangle alloc] initWithRect:aRect tag:t owner:anObject userData:data inside:flag]; [tracking_rects addObject:m]; return t; } - (NSArray *)trackingRectangles { return tracking_rects; } // // Dragging // - (BOOL)dragFile:(NSString *)filename fromRect:(NSRect)rect slideBack:(BOOL)slideFlag event:(NSEvent *)event { return NO; } - (void)dragImage:(NSImage *)anImage at:(NSPoint)viewLocation offset:(NSSize)initialOffset event:(NSEvent *)event pasteboard:(NSPasteboard *)pboard source:(id)sourceObject slideBack:(BOOL)slideFlag {} - (void)registerForDraggedTypes:(NSArray *)newTypes {} - (void)unregisterDraggedTypes {} // // Printing // - (NSData *)dataWithEPSInsideRect:(NSRect)aRect { return nil; } - (void)fax:(id)sender {} - (void)print:(id)sender {} - (void)writeEPSInsideRect:(NSRect)rect toPasteboard:(NSPasteboard *)pasteboard {} // // Pagination // - (void)adjustPageHeightNew:(float *)newBottom top:(float)oldTop bottom:(float)oldBottom limit:(float)bottomLimit {} - (void)adjustPageWidthNew:(float *)newRight left:(float)oldLeft right:(float)oldRight limit:(float)rightLimit {} - (float)heightAdjustLimit { return 0; } - (BOOL)knowsPagesFirst:(int *)firstPageNum last:(int *)lastPageNum { return NO; } - (NSPoint)locationOfPrintRect:(NSRect)aRect { return NSZeroPoint; } - (NSRect)rectForPage:(int)page { return NSZeroRect; } - (float)widthAdjustLimit { return 0; } // // Writing Conforming PostScript // - (void)addToPageSetup {} - (void)beginPage:(int)ordinalNum label:(NSString *)aString bBox:(NSRect)pageRect fonts:(NSString *)fontNames {} - (void)beginPageSetupRect:(NSRect)aRect placement:(NSPoint)location {} - (void)beginPrologueBBox:(NSRect)boundingBox creationDate:(NSString *)dateCreated createdBy:(NSString *)anApplication fonts:(NSString *)fontNames forWhom:(NSString *)user pages:(int)numPages title:(NSString *)aTitle {} - (void)beginSetup {} - (void)beginTrailer {} - (void)drawPageBorderWithSize:(NSSize)borderSize {} - (void)drawSheetBorderWithSize:(NSSize)borderSize {} - (void)endHeaderComments {} - (void)endPrologue {} - (void)endSetup {} - (void)endPageSetup {} - (void)endPage {} - (void)endTrailer {} // // NSCoding protocol // - (void)encodeWithCoder:aCoder { [super encodeWithCoder:aCoder]; NSLog(@"NSView: start encoding\n"); [aCoder encodeRect: frame]; [aCoder encodeRect: bounds]; [aCoder encodeObjectReference: super_view withName: @"Superview"]; [aCoder encodeObject: sub_views]; [aCoder encodeObjectReference: window withName: @"Window"]; [aCoder encodeObject: tracking_rects]; [aCoder encodeValueOfObjCType:@encode(BOOL) at: &is_flipped]; [aCoder encodeValueOfObjCType:@encode(BOOL) at: &is_rotated_from_base]; [aCoder encodeValueOfObjCType:@encode(BOOL) at: &is_rotated_or_scaled_from_base]; [aCoder encodeValueOfObjCType:@encode(BOOL) at: &opaque]; [aCoder encodeValueOfObjCType:@encode(BOOL) at: &needs_display]; [aCoder encodeValueOfObjCType:@encode(BOOL) at: &disable_autodisplay]; [aCoder encodeValueOfObjCType:@encode(BOOL) at: &post_frame_changes]; [aCoder encodeValueOfObjCType:@encode(BOOL) at: &autoresize_subviews]; NSLog(@"NSView: finish encoding\n"); } - initWithCoder:aDecoder { [super initWithCoder:aDecoder]; NSLog(@"NSView: start decoding\n"); frame = [aDecoder decodeRect]; bounds = [aDecoder decodeRect]; [aDecoder decodeObjectAt: &super_view withName: NULL]; sub_views = [aDecoder decodeObject]; [aDecoder decodeObjectAt: &window withName: NULL]; tracking_rects = [aDecoder decodeObject]; [aDecoder decodeValueOfObjCType:@encode(BOOL) at: &is_flipped]; [aDecoder decodeValueOfObjCType:@encode(BOOL) at: &is_rotated_from_base]; [aDecoder decodeValueOfObjCType:@encode(BOOL) at: &is_rotated_or_scaled_from_base]; [aDecoder decodeValueOfObjCType:@encode(BOOL) at: &opaque]; [aDecoder decodeValueOfObjCType:@encode(BOOL) at: &needs_display]; [aDecoder decodeValueOfObjCType:@encode(BOOL) at: &disable_autodisplay]; [aDecoder decodeValueOfObjCType:@encode(BOOL) at: &post_frame_changes]; [aDecoder decodeValueOfObjCType:@encode(BOOL) at: &autoresize_subviews]; NSLog(@"NSView: finish decoding\n"); return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.