ftp.nice.ch/Attic/openStep/developer/resources/MiscKit.2.0.5.s.gnutar.gz#/MiscKit2/Temp/MiscAutoTextScroller/MiscAutoTextScroller.m

This is MiscAutoTextScroller.m in view mode; [Download] [Up]

/* MiscAutoTextScroller.m created by stark on Fri 04-Apr-1997 */

#import "MiscAutoTextScroller.h"

	//	Private methods
@interface MiscAutoTextScroller(Private)

- (void)_reset;
- (void)_nextStep:sender;	//	I'm not sure of the case :-)

@end

	//	Public methods implementation
@implementation MiscAutoTextScroller

- (NSTextStorage *)textStorage
{	return [itsSourceText textStorage];
}

- (void)setTextStorage:(NSTextStorage *)aTextStorage
{	[[itsSourceText layoutManager] replaceTextStorage:aTextStorage];
	[self _reset];
	[self display];
}

- (BOOL)setTextFromRTFDPath:(NSString *)anRtfdPath
{	if (anRtfdPath)
	{	NSTextStorage *theStorage = [[[NSTextStorage alloc]
					initWithPath:anRtfdPath
					documentAttributes:NULL] autorelease];
		if (theStorage)
		{	[self setTextStorage:theStorage];
			return YES;
		}
	}
	return NO;
}

- (void)startScroll:sender
{	if ([self isScrolling])
		[self stopScroll:sender];
	[self _nextStep:nil];
}

- (void)stopScroll:sender
{	[self _reset];
	[self display];
}

- (BOOL)isScrolling
{	return itsState<=1;
}

- (NSTimeInterval)scrollTime
{	return itsScrollTime;
}

- (void)setScrollTime:(NSTimeInterval)aTotalTime
{	itsScrollTime = aTotalTime;
}

- (float)frameCountPerSecond
{	return itsFrameCountPerSeconds;
}

- (void)setFrameCountPerSecond:(float)aFrameCountPerSeconds
{	itsFrameCountPerSeconds = aFrameCountPerSeconds;
}

@end

	//	Private implementation
@implementation MiscAutoTextScroller(Private)

- initWithFrame:(NSRect)aFrame
{	[super initWithFrame:aFrame];
	itsScrollTime = 2;		//	50 pixels/seconds
	itsFrameCountPerSeconds = 25;	//	25 images/seconds (crappy)

	itsSourceText = [[NSTextView alloc] initWithFrame:[self frame]];

		//	We use the class name for enabling each subclass having a different RTFD by default
		//	We use the mainBundle because MiscKit is living in its own framework
		//	but the user want to put its info file in its own directory
		//	Not that this have the 'sad' side-effect of diabling a subclass that come from
		//	a framework to have its own auto-comment.
		//	I suppose this is too much magic...
	[self setTextFromRTFDPath:[[NSBundle mainBundle] pathForResource:[[self class] description] ofType:@"rtfd"]];

	return self;
}

- (void)dealloc
{	[itsBgImage release];
	[itsTextImage release];
	[itsSourceText release];
	[super dealloc];
}

- (void)_reset
{	[itsTextImage release];
	itsTextImage = 0;
	[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(_nextStep:) object:nil];
	itsState = 0;
}

- (void)_buildImgCache
{	NSRect theCover = [self convertRect:[self bounds] toView:nil];

	[[self window] disableFlushWindow];
	itsfIsBuildingCache = YES;
	[self display];
	itsfIsBuildingCache = NO;
	
	itsBgImage = [[NSImage alloc] initWithSize:theCover.size];
	[itsBgImage lockFocus];
       	NSCopyBits( [[self window] gState], theCover, NSMakePoint(0,0) );
	[itsBgImage unlockFocus];

	[[self window] enableFlushWindow];
}

- (void)_buildTextCache
{	NSRect theCover = [self convertRect:[self bounds] toView:nil];

	[itsTextImage release];
	itsTextImage = nil;

		//	Grab the content of the text
	[itsSourceText setDrawsBackground:NO];
	[itsSourceText setFrame:NSMakeRect(0,0,NSWidth(theCover),0)];
	[itsSourceText sizeToFit];
	itsTextImage = [[NSImage alloc] initWithSize:[itsSourceText bounds].size];
	[itsTextImage setFlipped:YES];
	[itsTextImage lockFocus];
		PSsetalpha( 0 );
		NSRectFill( [itsSourceText bounds] );
		[itsSourceText drawRect:[itsSourceText bounds]];
	[itsTextImage unlockFocus];
}

- (void)drawRect:(NSRect)aRect
{
		//	If we are building our background cache, we do not draw
	if (itsfIsBuildingCache)
		return;

		//	Get the background if we don't already have
	if (!itsBgImage)
		[self _buildImgCache];

		//	Get the text if we don't already have
	if (!itsTextImage)
		[self _buildTextCache];

		//	If scrolling, show the current position
	if ([self isScrolling])
	{	NSRect theRect = [self bounds];

		[itsBgImage compositeToPoint:[self bounds].origin operation:NSCompositeCopy];

		theRect.origin.y = ([itsTextImage size].height)*(1-itsState)-NSHeight(theRect);
//		NSLog( @"%@ %@", NSStringFromPoint( [self bounds].origin ), NSStringFromRect( theRect ) );
		[itsTextImage compositeToPoint:[self bounds].origin fromRect:theRect operation:NSCompositeSourceOver];
	}
}

- (void)_nextStep:sender
{	if (itsState>1)
	{	[self _reset];
		[self display];
	}
	else
	{	[self performSelector:@selector(_nextStep:) withObject:nil afterDelay:1.0/itsFrameCountPerSeconds];
		[self display];
		itsState += 1.0/(itsFrameCountPerSeconds*itsScrollTime*[itsTextImage size].height/100);
	}
}

- (void)setFrame:(NSRect)aFrame
{	[super setFrame:aFrame];
	[itsBgImage release];
	itsBgImage = nil;
	[itsTextImage release];
	itsTextImage = nil;
}

@end

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.