This is EdsndApp.m in view mode; [Download] [Up]
/* EdsndApp.m -- Implementation for EdsndApp object. * * Original code by Lee Boynton * Revision by James Pritchett, 10/89 * Version 1.01, 11/89 * Version 1.1, 12/89 * -- Added Stopwatch support * -- Re-arranged menu cell tags * Version 1.2, 1/90 * -- Added FFT display * -- Added enveloping * -- Added methods to retrieve flag values * -- Changed menu updating system * -- Changed all accessories to UpPanels and added updating * Version 1.3, 2/90 (Steven M. Boker) * -- Added Spectrum display * Version 1.31, 3/90 * -- EdsndApp now keeps track of the current Sound * Update for 2.0:, 3/91 * -- Removed NXWait/NXArrow calls */ #import "EdsndApp.h" #import "SoundDocument.h" #import "ScrollingSound.h" #import "EdSoundView.h" #import "Stopwatch.h" #import "FFT.h" #import "Envelope.h" #import "UpPanel.h" #import <string.h> #import <appkit/Form.h> #import <appkit/OpenPanel.h> #import <appkit/Cursor.h> #import <appkit/Panel.h> #import <appkit/Menu.h> #import <appkit/MenuCell.h> /* Tags on menu cells identify what conditions are necessary for them * to be active: */ #define NEEDSNIL 0 /* Always enabled */ #define NEEDSDOC 1 /* Needs an open document */ #define NEEDSSND 2 /* Needs some sound (i.e., non-empty document) */ #define NEEDSFILE 3 /* Needs a filename */ /* C FUNCTIONS NEEDED BY EdsndApp METHODS: * * getOpenPath() -- Gets a filename and path for the open command. * Uses an OpenPanel object to get the filename. */ static BOOL getOpenPath(char *buf) { static id openPanel = nil; BOOL ok; char const *fileTypes[2] = {0,0}; if (!openPanel) openPanel = [OpenPanel new]; /* panel for getting filename */ [NXApp setAutoupdate:NO]; /* OpenPanel object will prompt user for a filename and return it. */ if ([openPanel runModalForTypes:fileTypes]) { strcpy(buf,[openPanel filename]); [NXApp setAutoupdate:YES]; return YES; } else { [NXApp setAutoupdate:YES]; return NO; } } static void initMenu(id menu) /* * Sets the updateAction for every menu item. This function is recursive: * it calls itself to handle sub-menus. */ { int count; id matrix, cell; matrix = [menu itemList]; count = [matrix cellCount]; while (count--) { cell = [matrix cellAt:count :0]; [cell setUpdateAction:@selector(menuUpdate:) forMenu:menu]; if ([cell hasSubmenu]) initMenu([cell target]); } } /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ @implementation EdsndApp /* new -- create and initialize all variables */ + new { self = [super new]; openDoc = openSound = openFile = NO; currentSound = nil; } /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ /* appDidInit: -- issued when application is initialized * (since there's no delegate for the Application, the Application * will be issued this message) */ - appDidInit:sender { /* Set the update method for all menu cells */ initMenu([NXApp mainMenu]); [self setAutoupdate:YES]; return self; } /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ /* hide: -- Hide the Application, but stop any play first */ - hide:sender { /* Note: mainWindow is always the current SoundDocument (no other * windows in this application) * The SoundDocument is the delegate for its window. */ if (mainWindow) [[mainWindow delegate] stop:self]; return [super hide:sender]; } /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ /* terminate: -- Quit the Application, but save any unsaved files first */ - terminate:sender { id win; /* Pointer to window */ int choice; /* Go through window list any find any edited documents. Prompt user to * save them or not, and issue a save: command if necessary. */ while ((win = [self makeWindowsPerform:@selector(isDocEdited) inOrder:NO]) != nil) { [win orderFront:sender]; choice = NXRunAlertPanel("Quit", "%s is modified.\nSave it?", "Yes", "No", NULL, [win title]); switch (choice) { case NX_ALERTALTERNATE: [win setDocEdited:NO]; break; case NX_ALERTDEFAULT: [[win delegate] save:self]; break; } } [super terminate:sender]; } /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ /* newDocument: -- Create a new, empty SoundDocument */ - newDocument:sender { [SoundDocument new]; return self; } /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ /* open: -- Open a file in response to menu selection */ - open:sender { char pathname[1024]; id newDocument; if (getOpenPath(pathname)) { newDocument = [SoundDocument new]; [newDocument setFileName:pathname]; [newDocument load:self]; } return self; } /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ /* addSil: -- Translate input from AddPanel to EdSoundView */ - addSil:sender { float dur; dur = [addForm floatValueAt:0]; if (currentSound) [currentSound addSilence:dur]; [addPanel orderOut:self]; return self; } /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ /* stopwatch: -- Bring up the stopwatch panel */ - stopwatch:sender { /* Make the stopwatch if we haven't already done so */ if (watch == nil) { watch = [Stopwatch new]; watchPanel = [watch panel]; [watch setDelegate:self]; /* We're the delegate */ } [watchPanel makeKeyAndOrderFront:self]; return self; } /* stopwatchWillStart:, stopwatchDidStop: -- delegate methods for stopwatch */ - stopwatchWillStart:sender { id curDoc; if (openDoc) { curDoc = [[self mainWindow] delegate]; [watch setTarget:curDoc toStart:@selector(play:) andStop:@selector(stop:)]; } return self; } - stopwatchDidStop:sender { [watch setTarget:nil toStart:@selector(play:) andStop:@selector(stop:)]; return self; } /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ /* showFFT: -- Create and/or bring up the FFT panel */ - showFFT:sender { /* If the FFT manager doesn't exist, make it */ if (!FFTObj) FFTObj = [FFT new]; [FFTObj displayFFT:self]; return self; } /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ /* showEnv: -- Create and/or bring up the Envelope panel */ - showEnv:sender { /* If the envelope manager doesn't exist, make it */ if (!EnvObj) EnvObj = [Envelope new]; [[EnvObj envPanel] makeKeyAndOrderFront:self]; return self; } /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ /* isOpenDocument:, isOpenSound:, isOpenFile: -- set/reset flags to control * menu cells * isOpenDocument, isOpenSound, isOpenFile -- return those flags */ - isOpenDocument:(BOOL)flag { openDoc = flag; if (!flag) /* No doc means no sound or file */ openSound = openFile = flag; return self; } - isOpenSound:(BOOL)flag { openSound = flag; return self; } - isOpenFile:(BOOL)flag { openFile = flag; return self; } - (BOOL)isOpenDocument { return openDoc; } - (BOOL)isOpenSound { return openSound; } - (BOOL)isOpenFile { return openFile; } - isPlaying:(BOOL)flag { isPlaying = flag; if (!flag && (watch != nil)) /* Stop the watch if necc. */ [watch performStop:self]; return self; } /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ /* menuUpdate -- Update action for menu cells */ - menuUpdate:sender { /* We keep up with menu cells by their tag #'s. See above for * details. */ switch([sender tag]) { case NEEDSDOC: [sender setEnabled:openDoc]; break; case NEEDSSND: [sender setEnabled:openSound]; break; case NEEDSFILE: [sender setEnabled:openFile]; break; default: [sender setEnabled:YES]; break; } return self; } /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ /* panelUpdate: update action for UpPanels (accessories) * Panels are removed when there's no open document. */ - panelUpdate:sender { if (!openDoc) [sender orderOut:self]; return self; } /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ /* Get/set instance variables */ - setCurrentSound:aSoundView { currentSound = aSoundView; return self; } - currentSound { return currentSound; } - setAddForm:anObject { addForm = anObject; return self; } - setAddPanel:anObject { addPanel = anObject; [addPanel setUpdateAction:@selector(panelUpdate:) by:NXApp]; return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.