home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-03-22 | 28.2 KB | 1,034 lines |
- // WWSimpleMovieView is exactly that: a pretty simple view for showing movies.
- // It has a bunch of different behaviors to do all the obvious things:
- // all of the following do it at some given frames/second:
- // - plays movie either from the beginning each time or bounces
- // - plays movie continuously
- // - starts playing movie once when clicked, stops when clicked
- // - plays movie when the mouse is over it; resets when the mouse leaves
-
- // one thing that would be handy is if the view had a notion of a
- //control panel for itself. It might have two outlets, one which is the
- //controlPanelView, and some other view (say, a WW3DWell) could come
- //along and switch that view in so that the view might have some visible
- //control. This is sort of a bug of NS; no notion of objects having
- //control panels (i.e. the live version of an inspector).
-
- #import "WWSimpleMovieView.h"
- #import "aspectRatios.h"
- // for IB protocols
- #import <apps/InterfaceBuilder.h>
-
- // for mkdir()
- #import <sys/types.h>
- #import <sys/stat.h>
-
-
- @implementation WWSimpleMovieView
-
-
- #define WW_BOTTOMALIGNED 0
- #define WW_TOPALIGNED 1
-
-
- /*
- ==========================================================================
- subext() -- Remove extension from fname only if it is there.
-
- ==========================================================================
- */
- static char
- *subext(fname, ext)
- register char *fname, *ext;
- {
- int fl, el;
-
- for ( fl = strlen(fname), el = strlen(ext);
- --el > -1 && --fl > -1 && fname[fl] == ext[el]; )
- ;
- if (el == -1)
- { fname[fl] = '\0';
- }
- return(fname);
- }
-
-
- /*
- ==========================================================================
- basename() -- deletes any prefix ending in `/' and the suffix.
-
- ==========================================================================
- */
- static char
- *basename(str, sfx, dest)
- char *str, *sfx, *dest;
- {
- char temp[1024];
- char *p, *p1;
- char *subext();
-
- p = p1 = temp;
- strcpy(p, str);
- while (*p)
- { if (*p++ == '/')
- { p1 = p;
- }
- }
- strcpy (dest, subext(p1, sfx));
- return(dest);
- }
-
- + initialize { return [WWSimpleMovieView setVersion:3], self; }
-
-
- - showFrameAndIncrement:sender
- {
- if (drawCorrectly && (alpha < 1.0))
- { clearTheView = YES; [self display];
- clearTheView = NO; [window display];
- }
- else
- { clearTheView = NO; [self display];
- }
- NXPing();
- if (!stationaryFrameTE) // if we're not really playing, we're outta here
- { return self;
- }
-
- // check to see if we're at the last frame of the sequence
- if (goingForward)
- { if (currentFrameIndex == (frameCount - 1)) // we're at the end!
- { if (loop)
- { currentFrameIndex = 0;
- }
- else
- { currentFrameIndex--;
- goingForward = NO;
- }
- }
- else // more frames to go...
- { currentFrameIndex++;
- }
- }
- else // going backwards; 0 is the end frame
- { if (!currentFrameIndex) // we're at the end!
- { if (loop) // no way; we don't backwards if we're looping, doofus...
- { NXLogError("shouldn't be here, pal.\n");
- }
- goingForward = YES;
- currentFrameIndex++;
- }
- else // keep counting down
- { currentFrameIndex--;
- }
- }
-
- movieImage = [imageList objectAt:currentFrameIndex];
- return self;
- }
-
- void nextFrame(DPSTimedEntry teNumber, double now, void *userData)
- {
- id myObj = (id)userData;
-
- [myObj showFrameAndIncrement:nil];
- return ;
- }
-
-
-
- - beginStationaryBehavior
- {
- // make sure that I have some images in my list
- if (![imageList count])
- { return self;
- }
- goingForward = YES;
- stationaryFrameTE = DPSAddTimedEntry(frameTimeIncr,
- (DPSTimedEntryProc)nextFrame,
- self, NX_MODALRESPTHRESHOLD);
- if (stationaryBehavior == WW_PLAY_MOUSE_IN)
- { [self setMyTrackingRect:YES];
- }
- return self;
- }
-
- - endStationaryBehavior
- {
- if (stationaryFrameTE)
- { DPSRemoveTimedEntry(stationaryFrameTE);
- stationaryFrameTE = 0;
- }
-
- return self;
- }
-
- - copyFromZone:(NXZone *)zone
- {
- id newCopy = [super copyFromZone:zone];
-
- if (frameCount)
- { // rather than copy through the movie data, we'll just
- // mark both this instance and the new one as using
- // a shared movie
- [self setMovieIsShared:YES];
- [newCopy setMovieIsShared:YES];
- }
-
- return newCopy;
- }
-
- - free
- {
- if (controlPanel)
- { [controlPanel setFreeWhenClosed:NO];
- [controlPanel close];
- [controlPanel free];
- controlPanel = nil;
- }
- [self endStationaryBehavior];
- if (stationaryBehavior == WW_PLAY_MOUSE_IN)
- { [self setMyTrackingRect:NO];
- }
-
- if (!movieIsShared)
- { [imageList freeObjects];
- }
- [imageList free];
-
- if (!imageIsShared)
- { [image free];
- }
-
- return [super free];
- }
-
- - initFrame:(const NXRect *)r
- {
- [super initFrame:r];
- backgroundColor = NXConvertRGBToColor(0.96, 1.0, 0.6);
- borderType = 0;
- alpha = 1.0;
- image = nil;
- movieImage = nil;
- imageList = [[List alloc] init];
- imageIsShared = NO;
- movieIsShared = NO;
- frameCount = 0;
- aspectRatioType = WW_ASPECT_DONT_CARE;
- aspectRatio = 1.0;
- scaleToFit = NO;
- imageUnder = NO;
- horizontalLayoutType = NX_LEFTALIGNED;
- verticalLayoutType = WW_BOTTOMALIGNED;
- fps = 15.0;
- frameTimeIncr = 1.0/fps;
- loop = NO; // in other words, "breathe"
- stationaryBehavior = WW_PLAY_MOUSE_CLICK;
- stationaryFrameTE = (DPSTimedEntry)0;
- sink = NO;
- source = NO;
- archiveImageData = YES;
- archiveMovieData = YES;
- trackingRect = 0;
- drawCorrectly = YES;
- controlPanel = nil;
-
- if (stationaryBehavior == WW_PLAY_CONTINUOUS)
- { [self beginStationaryBehavior];
- }
-
- return self;
- }
-
- - awake
- {
- [super awake];
- stationaryFrameTE = (DPSTimedEntry)0;
- trackingRect = 0;
- if ([NXApp conformsTo:@protocol(IB)]) // what a hacque!! (def: "hacqe: a particularly baroque (in both senses of the word...) hack")
- { [self perform:@selector(awakeFromNib) with:nil afterDelay:0.01 cancelPrevious:NO];
- // the reason we do this is because I'm not certain that if we awake in IB our "window" will be set yet.
- }
- currentFrameIndex = 0;
- frameCount = [imageList count];
- controlPanel = nil;
- if (frameCount)
- { movieImage = [imageList objectAt:currentFrameIndex];
- if (stationaryBehavior == WW_PLAY_CONTINUOUS)
- { [self beginStationaryBehavior];
- }
- }
-
- return self;
- }
-
- - awakeFromNib
- {
- if (stationaryBehavior == WW_PLAY_MOUSE_IN)
- { [self setMyTrackingRect:YES];
- }
- return self;
- }
-
-
- #define EPSILON 10
-
- - sizeTo:(NXCoord)width :(NXCoord)height
- {
- // don't want to make it too small...
- if (width < EPSILON) return nil;
- if (height < EPSILON) return nil;
-
-
- // let's say it comes in at 100, 100 and you're supposed to be constrained to 4:3
- // you don't want it to get bigger than 100, 100, so... you frob the width, not the height
- switch (aspectRatioType)
- { case WW_ASPECT_DONT_CARE:
- aspectRatio = width/height;
- break;
- case WW_ASPECT_NTSC: // 1.33:1
- height = width/1.33;
- aspectRatio = 1.33;
- break;
- case WW_ASPECT_SQUARE: // 1:1
- if (width < height)
- { height = width;
- }
- else
- { width = height;
- }
- aspectRatio = 1.0;
- break;
- case WW_ASPECT_CUSTOM: //aspectX:aspectY
- if (aspectRatio < 1.0)
- { width = height * aspectRatio;
- }
- else
- { height = width/aspectRatio;
- }
- break;
- default:
- NXLogError("unknown aspect ratio type: %d", aspectRatioType);
- break;
- }
-
- [super sizeTo:width :height];
- [self display];
- if (stationaryBehavior == WW_PLAY_MOUSE_IN)
- { [self setMyTrackingRect:YES];
- }
-
- return self;
- }
-
- - setBorderType:(int)newBorderType { borderType = newBorderType; return self; }
- - (int)borderType { return borderType; }
-
- - setFPS:(float)newFPS { fps = newFPS; frameTimeIncr = 1.0/fps; return self; }
- - (float)fps { return fps; }
-
- //
- - sizeToImage:sender
- {
- NXSize s;
-
-
- if (image)
- { [image getSize:&s];
- [self sizeTo:s.width :s.height];
- }
- return self;
- }
-
- - sizeToMovie:sender
- {
- NXSize s;
-
-
- if (movieImage)
- { [movieImage getSize:&s];
- [self sizeTo:s.width :s.height];
- }
- return self;
- }
-
- - setScaleToFit:(BOOL)flag { scaleToFit = flag; return self; }
- - (BOOL)scaleToFit { return scaleToFit; }
- - setImageUnder:(BOOL)flag { imageUnder = flag; return self; }
- - (BOOL)imageUnder { return imageUnder; }
-
- - (int)aspectRatioType { return aspectRatioType; }
- - (float)aspectRatio { return aspectRatio; }
- - setAspectRatioFromMatrix:sender
- {
- NXRect newRect;
-
-
- [self getFrame:&newRect];
- aspectRatioType = [[sender selectedCell] tag];
- switch (aspectRatioType)
- { case WW_ASPECT_DONT_CARE:
- break;
- case WW_ASPECT_NTSC: // 1.33:1
- newRect.size.height = newRect.size.width/1.33;
- break;
- case WW_ASPECT_SQUARE: // 1:1
- if (newRect.size.width < newRect.size.height)
- { newRect.size.height = newRect.size.width;
- }
- else
- { newRect.size.width = newRect.size.height;
- }
- break;
- case WW_ASPECT_CUSTOM: //aspectX:aspectY
- if (aspectRatio < 1.0)
- { newRect.size.width = newRect.size.height * aspectRatio;
- }
- else
- { newRect.size.height = newRect.size.width/aspectRatio;
- }
- break;
- default:
- NXLogError("unknown aspect ratio type: %d", aspectRatioType);
- break;
- }
- [self sizeTo:newRect.size.width :newRect.size.height];
-
- return self;
- }
- //
- - setAspectRatio:sender
- {
- NXRect newRect;
-
-
- [self getFrame:&newRect];
- aspectRatio = [sender floatValue];
-
- if (aspectRatioType != WW_ASPECT_CUSTOM)
- { return self;
- }
- if (aspectRatio < 1.0)
- { newRect.size.width = newRect.size.height * aspectRatio;
- }
- else
- { newRect.size.height = newRect.size.width/aspectRatio;
- }
- [self sizeTo:newRect.size.width :newRect.size.height];
-
- return self;
- }
- //
- - setHorizontalLayoutFromMatrix:sender { horizontalLayoutType = [[sender selectedCell] tag]; return self; }
- - (int)horizontalLayoutType { return horizontalLayoutType; }
-
- - setVerticalLayoutFromMatrix:sender { verticalLayoutType = [[sender selectedCell] tag]; return self; }
- - (int)verticalLayoutType { return verticalLayoutType; }
-
-
- - (NXColor) backgroundColor { return backgroundColor; }
- - setBackgroundColor:(NXColor)c { return backgroundColor = c, self; }
- - (float) alpha { return alpha; }
- - setBackgroundAlpha:(float)n { return alpha = n, self; }
-
- - (int)stationaryBehavior { return stationaryBehavior; }
- - setStationaryBehavior:(int)n
- {
- [self endStationaryBehavior];
- stationaryBehavior = n;
- if (stationaryBehavior == WW_PLAY_CONTINUOUS)
- { [self beginStationaryBehavior];
- }
- if (stationaryBehavior == WW_PLAY_MOUSE_IN)
- { [self setMyTrackingRect:YES];
- }
- return self;
- }
- - setStationaryBehaviorFromMatrix:sender
- {
- [self setStationaryBehavior:[[sender selectedCell] tag]];
- return self;
- }
-
- - setLoop:(BOOL)n { loop = n; return self; }
- - (BOOL)loop { return loop; }
-
- - setArchiveImageData:(BOOL)n { archiveImageData = n; return self; }
- - (BOOL)archiveImageData { return archiveImageData; }
-
- - setArchiveMovieData:(BOOL)n { archiveMovieData = n; return self; }
- - (BOOL)archiveMovieData { return archiveMovieData; }
-
- - setDrawCorrectly:(BOOL)n { drawCorrectly = n; return self; }
- - (BOOL)drawCorrectly { return drawCorrectly; }
-
- - (int)frameCount { return frameCount; }
-
- - setImageIsShared:(BOOL)flag { imageIsShared = flag; return self; }
- - setMovieIsShared:(BOOL)flag { movieIsShared = flag; return self; }
-
- - removeMovie:sender
- {
- if (!movieIsShared)
- { [imageList freeObjects];
- movieImage = nil;
- }
- else
- { [imageList empty];
- movieImage = nil;
- }
- return self;
-
- }
-
- - setAnimDir:(const char *)filename
- {
- BOOL done = NO;
- char theBaseName[MAXPATHLEN+1],
- tiffFileName[MAXPATHLEN+1],
- *animSuffixPtr;
- int frameIndex = 1;// remind me to slap Keith next time I see him...
-
-
- if (filename && *filename)
- { if (!movieIsShared)
- { [imageList freeObjects];
- }
- movieImage = nil;
- done = NO;
- animSuffixPtr=rindex(filename, '.');
- if (animSuffixPtr && strcmp(animSuffixPtr, ".anim"))
- { NXLogError("the file %s doesn't end in anim, dude!\n", filename);
- return nil;
- }
- basename(filename, ".anim", theBaseName);
- while (!done)
- { sprintf(tiffFileName, "%s/%s.%d.tiff", filename, theBaseName, frameIndex);
- // does the file exist?
- if (access(tiffFileName, R_OK) == -1)
- { done = YES; // nope; we're outta here
- }
- else
- { movieImage = [NXImage findImageNamed:tiffFileName];
- if (!movieImage)
- { movieImage = [[NXImage alloc] init];
- if (archiveMovieData)
- { [movieImage setDataRetained:YES];
- }
- if (![movieImage loadFromFile:tiffFileName])
- { NXLogError("unable to load image from file <%s>\n", tiffFileName);
- done = YES; // guess the last image was bad; a common occurrence when the anim is still being generated...
- }
- }
- [imageList insertObject:movieImage at:(frameIndex - 1)]; // I really gotta whap Keith; 1 based indices; jeez...
- frameIndex++;
- }
- }
- }
- frameCount = [imageList count];
- currentFrameIndex = 0;
- movieImage = [imageList objectAt:currentFrameIndex];
- clearTheView = YES; [self display];
- clearTheView = NO; [window display];
- NXPing();
- if (stationaryBehavior == WW_PLAY_CONTINUOUS)
- { [self beginStationaryBehavior];
- }
-
- return self;
- }
-
-
-
- - removeImage:sender
- {
- if (!imageIsShared)
- { [image free];
- }
- image = nil;
- return self;
- }
-
- - setImageFile:(const char *)filename
- {
- if (!imageIsShared)
- { [image free];
- }
- image = nil;
- if (filename && *filename)
- { image = [NXImage findImageNamed:filename];
- if (!image)
- { image = [[NXImage alloc] init];
- [image setDataRetained:YES];
- if (![image loadFromFile:filename])
- { NXLogError("unable to load image from file <%s>\n", filename);
- return nil;
- }
- }
- }
- clearTheView = YES; [self display];
- clearTheView = NO; [window display];
- NXPing();
- return self;
- }
-
- - setImage:i
- {
- if (!imageIsShared)
- { [image free];
- }
- image = i;
- clearTheView = YES; [self display];
- clearTheView = NO; [window display];
- NXPing();
- return self;
- }
- - image { return image; }
-
- - movieImage { return movieImage; }
-
-
- - drawSelf:(const NXRect *)theRect :(int)count
- {
- NXPoint p = {0.0, 0.0};
- NXSize imageSize, movieSize;
-
-
- if (clearTheView)
- { NXSetColor(backgroundColor);
- PSsetalpha(0.0);
- PScompositerect(theRect->origin.x, theRect->origin.y,
- theRect->size.width, theRect->size.height,
- NX_SOVER);
- return self;
- }
-
- NXSetColor(backgroundColor);
- if (!frameCount || drawCorrectly) // if there's no movie or we're being anal, use my alpha value
- { PSsetalpha(alpha);
- }
- else // otherwise, make it opaque, since the other views in the window aren't being redrawn too
- { PSsetalpha(1.0);
- }
-
- PScompositerect(theRect->origin.x, theRect->origin.y,
- theRect->size.width, theRect->size.height,
- NX_SOVER);
-
- [image getSize:&imageSize];
- [movieImage getSize:&movieSize];
-
- switch (verticalLayoutType)
- { case WW_BOTTOMALIGNED:
- p.y = 0.0;
- break;
- case WW_TOPALIGNED:
- if (imageSize.height > movieSize.height)
- { p.y = theRect->size.height - imageSize.height;
- }
- else
- { p.y = theRect->size.height - movieSize.height;
- }
- break;
- default:
- p.y = 0.0;
- break;
- }
- switch (horizontalLayoutType)
- { case NX_LEFTALIGNED:
- p.x = 0.0;
- break;
- case NX_RIGHTALIGNED:
- if (imageSize.width > movieSize.width)
- { p.x = theRect->size.width - imageSize.width;
- }
- else
- { p.x = theRect->size.width - movieSize.width;
- }
- break;
- case NX_CENTERED:
- if (imageSize.width > movieSize.width)
- { if (theRect->size.width > imageSize.width)
- { p.x = (theRect->size.width - imageSize.width)/2.0;
- }
- else
- { p.x = 0.0;
- }
- }
- else
- { if (theRect->size.width > movieSize.width)
- { p.x = (theRect->size.width - movieSize.width)/2.0;
- }
- else
- { p.x = 0.0;
- }
- }
-
- if (imageSize.height > movieSize.height)
- { if (theRect->size.height > imageSize.height)
- { p.y = (theRect->size.height - imageSize.height)/2.0;
- }
- else
- { p.y = 0.0;
- }
- }
- else
- { if (theRect->size.height > movieSize.height)
- { p.y = (theRect->size.height - movieSize.height)/2.0;
- }
- else
- { p.y = 0.0;
- }
- }
- break;
- default:
- p.x = 0.0;
- break;
- }
-
- if (imageUnder)
- { [image composite:NX_SOVER toPoint:&p];
- [movieImage composite:NX_SOVER toPoint:&p];
- }
- else
- { [movieImage composite:NX_SOVER toPoint:&p];
- [image composite:NX_SOVER toPoint:&p];
- }
-
- if (borderType)
- { NXRect r = *theRect;
-
-
- PSsetalpha(1.0);
-
- r.origin.x++; r.origin.y--;
- NXSetColor(NX_COLORBLACK); NXFrameRect(&r);
-
- r.origin.x--, r.origin.y++;
- NXSetColor(NX_COLORGRAY); NXFrameRect(&r);
-
- r.origin.x--; r.size.width++; r.size.height++;
- NXSetColor(NX_COLORWHITE); NXFrameRect(&r);
- }
-
- return self;
- }
-
- - (BOOL)acceptsFirstResponder { return YES; }
-
- - setMyTrackingRect:(BOOL)flag
- {
- NXRect visible;
-
-
- if (trackingRect)
- { [window discardTrackingRect:trackingRect];
- trackingRect = 0;
- }
- if (flag)
- { if ([self getVisibleRect:&visible])
- { [self convertRect:&visible toView:nil];
- [window setTrackingRect:&visible inside:NO owner:self tag:(int)self left:NO right:NO];
- trackingRect = (int)self;
- }
- }
- return self;
- }
-
- // might want to allow alt-click to move only one frame...
- - mouseDown:(NXEvent *)theEvent
- {
- if (theEvent->flags & NX_COMMANDMASK) // show the control panel
- { [self loadControlPanel];
- return self;
- }
- if (stationaryBehavior == WW_PLAY_MOUSE_CLICK)
- { if (!stationaryFrameTE) // is it running?
- { if (theEvent->flags & NX_ALTERNATEMASK) // click one frame
- { stationaryFrameTE = (DPSTimedEntry)1; // set it to something so the frame gets incremented...
- [self showFrameAndIncrement:nil];
- stationaryFrameTE = 0;
- }
- else
- { [self beginStationaryBehavior]; // start it up
- }
- }
- else
- { [self endStationaryBehavior]; // stop it
- }
- }
- return self;
- }
-
- - mouseEntered:(NXEvent *)theEvent
- {
- if (!stationaryFrameTE && (stationaryBehavior == WW_PLAY_MOUSE_IN))
- { [window makeFirstResponder:self]; // do I need to do this?
- [self beginStationaryBehavior];
- }
- return self;
- }
-
- - mouseExited:(NXEvent *)theEvent
- {
- if (stationaryFrameTE && (stationaryBehavior == WW_PLAY_MOUSE_IN))
- { [self endStationaryBehavior];
- }
- return self;
- }
-
- - (const char *)getInspectorClassName { return "WWSimpleMovieViewIBInspector"; }
-
-
- // Control Panel stuff (stolen from my IBInspector
-
-
- - loadControlPanel
- {
- char buf[MAXPATHLEN + 1];
- id bundle;
-
-
- // we want to support two different things here.
- // 1st scenario: lots of MovieViews, screen space is expensive, we want to have these control panels
-
- if (!controlPanel)
- { bundle = [NXBundle bundleForClass:[self class]];
- [bundle getPath:buf forResource:"WWSimpleMovieViewControlPanel" ofType:"nib"];
- [NXApp loadNibFile:buf owner:self withNames:NO fromZone:[self zone]];
- if (!controlPanel)
- { NXLogError("problem loading WWSimpleMovieViewControlPanel\n");
- return nil;
- }
- [controlPanel setDelegate:self];
- }
- [self revertControlPanel:nil];
- [controlPanel makeKeyAndOrderFront:self];
- return self;
- }
-
-
- - revertControlPanel:sender
- {
- [theColor setColor:[self backgroundColor]];
- [alphaSlider setFloatValue:[self alpha]];
- if ([self drawCorrectly])
- { [alphaSlider setEnabled:YES];
- }
- else
- { if ( [self frameCount])
- { [alphaSlider setEnabled:NO];
- }
- else
- { [alphaSlider setEnabled:YES];
- }
- }
- if ([self archiveImageData])
- { [theImage setStringValue:""];
- }
- else
- { [theImage setStringValue:[[self image] name]];
- }
-
- if ([self archiveMovieData])
- { [theImage setStringValue:""];
- }
- else
- { [theMovie setStringValue:[[self movieImage] name]];
- }
-
- [drawCorrectlySwitch setIntValue:[self drawCorrectly]];
- [aspectRatioMatrix selectCellWithTag:[self aspectRatioType]];
- [horizontalLayoutMatrix selectCellWithTag:[self horizontalLayoutType]];
- [verticalLayoutMatrix selectCellWithTag:[self verticalLayoutType]];
- [customAspectRatioText setFloatValue:[self aspectRatio]];
- [customAspectRatioText setEnabled:([self aspectRatioType] == WW_ASPECT_CUSTOM)];
- [scaleSwitch setIntValue:(int)[(WWSimpleMovieView *)self scaleToFit]];
- [imageUnderSwitch setIntValue:[self imageUnder]];
- [rotateTo setFloatValue:[self frameAngle]];
- [borderTypeMatrix selectCellWithTag:[self borderType]];
- [stationaryBehaviorMatrix selectCellWithTag:[self stationaryBehavior]];
- [loopSwitch setIntValue:[self loop]];
- [archiveMovieDataSwitch setIntValue:[self archiveMovieData]];
- [archiveImageDataSwitch setIntValue:[self archiveImageData]];
-
- [fpsText setFloatValue:[self fps]];
- clearTheView = YES; [self display];
- clearTheView = NO; [window display]; NXPing();
-
- return self;
- }
-
- - takeColor_:s { [self setBackgroundColor:[theColor color]]; [self revertControlPanel:nil]; return self; }
- - setAlpha_:s { [self setBackgroundAlpha:[s floatValue]]; [self revertControlPanel:nil]; return self; }
- - setImage_:s { [self setImageFile:(char *)[s stringValue]]; [self revertControlPanel:nil]; return self; }
- - setMovie_:s { [self setAnimDir:(char *)[s stringValue]]; [self revertControlPanel:nil]; return self; }
- - setAspectRatio_:s { [self setAspectRatio:s]; [self revertControlPanel:nil]; return self; }
- - setImageUnder_:s { [self setImageUnder:[s intValue]]; [self revertControlPanel:nil]; return self; }
- - setScale_:s { [self setScaleToFit:[s intValue]]; [self revertControlPanel:nil]; return self; }
- - setAspectRatioFromMatrix_:s { [self setAspectRatioFromMatrix:s]; [self revertControlPanel:nil]; return self; }
- - setHorizontalLayoutFromMatrix_:s { [self setHorizontalLayoutFromMatrix:s]; [self revertControlPanel:nil]; return self; }
- - setBorderTypeFromMatrix_:s { [self setBorderType:[[s selectedCell] tag]]; [self revertControlPanel:nil]; return self; }
- - setVerticalLayoutFromMatrix_:s { [self setVerticalLayoutFromMatrix:s]; [self revertControlPanel:nil]; return self; }
- - setFPS_:s { [self setFPS:[s floatValue]]; [self revertControlPanel:nil]; return self; }
- - setStationaryBehaviorFromMatrix_:s { [self setStationaryBehaviorFromMatrix:s]; [self revertControlPanel:nil]; return self; }
- - setLoop_:s { [self setLoop:[s intValue]]; [self revertControlPanel:nil]; return self; }
- - setArchiveMovieData_:s { [self setArchiveMovieData:[s intValue]]; [self revertControlPanel:nil]; return self; }
- - setArchiveImageData_:s { [self setArchiveImageData:[s intValue]]; [self revertControlPanel:nil]; return self; }
- - setDrawCorrectly_:s { [self setDrawCorrectly:[s intValue]]; [self revertControlPanel:nil]; return self; }
-
- - rotateTo_:s { [self rotateTo:[s floatValue]]; [self display]; [self revertControlPanel:nil]; return self; }
-
- - sizeToImage_:s { [self sizeToImage:s]; [self display]; [self revertControlPanel:nil]; return self; }
- - sizeToMovie_:s { [self sizeToMovie:s]; [self display]; [self revertControlPanel:nil]; return self; }
-
- - saveImage:sender
- {
- static id savePanel=nil;
- NXStream *ts;
-
-
- if (!savePanel)
- { savePanel=[SavePanel new];
- }
-
- [savePanel setRequiredFileType:"tiff"];
- if([savePanel runModal])
- { ts = NXOpenMemory(NULL, 0, NX_WRITEONLY);
- [image writeTIFF:ts allRepresentations:NO usingCompression:NX_TIFF_COMPRESSION_LZW andFactor:1.0];
- NXSaveToFile(ts, [savePanel filename]);
- NXCloseMemory(ts,NX_FREEBUFFER);
- }
-
- return self;
- }
-
- - saveMovie:sender
- {
- static
- id savePanel=nil;
- NXStream *ts;
- int ret, i;
- char imageNameBase[MAXPATHLEN+1];
- char imageFilename[MAXPATHLEN+1];
- char *animFilename;
-
-
- if (!savePanel)
- { savePanel=[SavePanel new];
- }
-
- [savePanel setRequiredFileType:"anim"];
- if([savePanel runModal])
- { // this is a little dangerous, but hey, it's faster...
- animFilename = (char *)[savePanel filename];
- ret = mkdir(animFilename, 0777);
- if (ret)
- { NXLogError("couldn't save anim to %s", animFilename);
- return nil;
- }
- basename(animFilename, ".anim", imageNameBase);
-
- for (i = 1; i < frameCount; i++)
- { ts = NXOpenMemory(NULL, 0, NX_WRITEONLY);
- if (!ts)
- { NXLogError("unable to open a memory stream!\n");
- return nil;
- }
- if (![[imageList objectAt:(i-1)] writeTIFF:ts allRepresentations:NO usingCompression:NX_TIFF_COMPRESSION_LZW andFactor:1.0])
- { NXLogError("unable to write image %d to a memory stream!\n", i);
- NXCloseMemory(ts, NX_FREEBUFFER);
- return nil;
- }
- sprintf(imageFilename, "%s/%s.%d.tiff", animFilename, imageNameBase, i);
- if (NXSaveToFile(ts, imageFilename))
- { NXLogError("unable to save memory stream to file <%s>\n", imageFilename);
- NXCloseMemory(ts, NX_FREEBUFFER);
- return nil;
- }
- NXCloseMemory(ts, NX_SAVEBUFFER);
- }
- ts = NXOpenMemory(NULL, 0, NX_WRITEONLY);
- if (!ts)
- { NXLogError("unable to open a memory stream!\n");
- return nil;
- }
- if (![[imageList objectAt:(i-1)] writeTIFF:ts allRepresentations:NO usingCompression:NX_TIFF_COMPRESSION_LZW andFactor:1.0])
- { NXLogError("unable to write image %d to a memory stream!\n", i);
- NXCloseMemory(ts, NX_FREEBUFFER);
- return nil;
- }
- sprintf(imageFilename, "%s/%s.%d.tiff", animFilename, imageNameBase, i);
- if (NXSaveToFile(ts, imageFilename))
- { NXLogError("unable to save memory stream to file <%s>\n", imageFilename);
- NXCloseMemory(ts, NX_FREEBUFFER);
- return nil;
- }
- NXCloseMemory(ts, NX_FREEBUFFER);
- }
-
- return self;
- }
-
-
- - windowWillClose:sender
- {
- if (controlPanel && (sender == controlPanel))
- { controlPanel = nil;
- }
- return self;
- }
-
-
-
- #define typeVectorVersion1 "@fifcciiiffcicccc@"
- #define typeValuesVersion1 &image, &alpha, &aspectRatioType, &aspectRatio, &imageUnder, &scaleToFit, &borderType, &horizontalLayoutType, &verticalLayoutType, &fps, &frameTimeIncr, &loop, &stationaryBehavior, &sink, &source, &archiveImageData, &archiveMovieData, &imageList
-
- #define typeVectorVersion2 "@fifcciiiffcicccc@c"
- #define typeValuesVersion2 &image, &alpha, &aspectRatioType, &aspectRatio, &imageUnder, &scaleToFit, &borderType, &horizontalLayoutType, &verticalLayoutType, &fps, &frameTimeIncr, &loop, &stationaryBehavior, &sink, &source, &archiveImageData, &archiveMovieData, &imageList, &drawCorrectly
-
- #define typeVector "@fifcciiiffcicccc@ccc"
- #define typeValues &image, &alpha, &aspectRatioType, &aspectRatio, &imageUnder, &scaleToFit, &borderType, &horizontalLayoutType, &verticalLayoutType, &fps, &frameTimeIncr, &loop, &stationaryBehavior, &sink, &source, &archiveImageData, &archiveMovieData, &imageList, &drawCorrectly, &imageIsShared, &movieIsShared
-
- - read:(NXTypedStream*)stream
- {
- int version;
- [super read:stream];
-
-
- version = NXTypedStreamClassVersion(stream, "WWSimpleMovieView");
- if (version == 0) NXReadTypes(stream, "i", &version), version=1;
- if (version == 1)
- { NXReadTypes(stream, typeVectorVersion1, typeValuesVersion1);
- backgroundColor = NXReadColor(stream);
- drawCorrectly = YES;
- imageIsShared = NO;
- movieIsShared = NO;
- }
- if (version == 2)
- { NXReadTypes(stream, typeVectorVersion2, typeValuesVersion2);
- backgroundColor = NXReadColor(stream);
- imageIsShared = NO;
- movieIsShared = NO;
- }
- if (version == 3)
- { NXReadTypes(stream, typeVector, typeValues);
- backgroundColor = NXReadColor(stream);
- }
- return self;
- }
-
-
- - write:(NXTypedStream *)stream
- {
- [super write:stream];
- NXWriteTypes(stream, typeVector, typeValues);
- NXWriteColor(stream, backgroundColor);
-
- return self;
- }
-
-
-
- @end
-