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.