This is eTAudioUI.m in view mode; [Download] [Up]
///////////////////////////////////////////////////////////////////////////////
// FILENAME: eTAudioUI.m
// SUMMARY: User Interface for Audio annotations to eText documents
// SUPERCLASS: eTAudioUI:eTImageUI:Object
// INTERFACE: None
// PROTOCOLS: <Inspectable>
// AUTHOR: Rohit Khare
// COPYRIGHT: (c) 1994 California Institure of Technology, eText Project
///////////////////////////////////////////////////////////////////////////////
// IMPLEMENTATION COMMENTS
// watch for hacks vis a vis sound display, play loops, and meters.
///////////////////////////////////////////////////////////////////////////////
// HISTORY
// 07/24/94: Rearchitected for PR1/eTImage
// 01/24/94: Created. Derived largely from Version3's temporary Hypertext
// '93 hack. Renamed as eTAudio and aTAudioUI.
///////////////////////////////////////////////////////////////////////////////
#import "eTAudioUI.h"
@implementation eTAudioUI
// id audioPanel;
// id audioView;
// id etAudio;
// id nameField;
// id eraseButton;
// id pauseButton;
// id playButton;
// id recordButton;
// id stopButton;
// id soundMeter;
// id soundView;
- setAnnotation:newAudio
{
id theSound;
if (etAudio == newAudio) return self;
[super setAnnotation:newAudio]; // this is an awkward naming of the "chain"
// properly unload the old audio
[soundMeter stop:self];
[soundMeter setSound:nil];
[soundView stop:self];
[[soundView sound] setDelegate:nil];
if ([etAudio respondsTo:@selector(audioEnded)])
[etAudio audioEnded];
etAudio = newAudio;
[nameField setStringValue:[etAudio audioName]];
[playButton setState:0];
[pauseButton setState:0];
[stopButton setState:0];
[recordButton setState:0];
theSound = [etAudio sound];
[soundView setSound:theSound];
[theSound setDelegate:self];
[soundView setDelegate:self]; // redundant, but hey...
[soundMeter setSound:theSound];
// There ought to be a link switch somewhere on that damn panel...
// [linkSwitch setState:[etAudio isAudioLinked];
return self;
}
- soundView {return soundView;}
- soundMeter {return soundMeter;}
///////////////////////////////////
+ new
{
static eTAudioUI *ui = nil;
if (!ui) {
ui = [[eTAudioUI alloc] init];
}
return ui;
}
- init
{
char buf[MAXPATHLEN];
NXBundle *bundle;
[super init];
bundle = [NXBundle bundleForClass:[self class]];
if ( [bundle getPath:buf forResource:"eTAudioUI" ofType:"nib"] ) {
[NXApp loadNibFile:buf owner:self withNames:NO];
} else {
NXLogError("NIB not found: eTAudioUI");
}
audioView = [audioPanel contentView];
return self;
}
- free {return self;}
///////////////////////////////////
#define PROP "Audio Properties"
- (const NXAtom *) types
{
static NXAtom *types = NULL;
if (!types) {
int i;
const NXAtom *superTypes = [super types];
for(i=0;superTypes[i];i++);
i++; // make room for terminating NULL
i++; // make room for our type
types = malloc(i * sizeof(NXAtom));
types[0] = NXUniqueString(PROP);
for(i=0;superTypes[i];i++) types[i+1] = superTypes[i];
types[i+1] = NULL;
}
return types;
}
- (const char *) inspectorTitle
{
return NXUniqueString("Audio");
}
- resignInspector: (View *) oldInspector ofType: (const char *) type
{
if (oldInspector == audioView) {
[soundMeter stop:self];
[soundView resignFirstResponder];
[audioView removeFromSuperview]; // keep it attached to some window
[audioPanel setContentView:audioView];
} else
[super resignInspector:oldInspector ofType:type];
return self;
}
- activateInspector: (View *) newInspector ofType: (const char *) type
{
if (newInspector == audioView) {
//anything special here?
switch ([[soundView soundBeingProcessed] status]) {
case NX_SoundPlayingPaused:
case NX_SoundRecordingPaused:
case NX_SoundPlaying:
case NX_SoundRecording: [soundMeter run:self]; break;
}
[soundView setEditable:[etAudio isAudioMutable]];
[nameField setEditable:[etAudio isAudioMutable]];
} else
[super activateInspector:newInspector ofType:type];
return self;
}
- inspectorForType:(const char *) type
{
if(!strcmp(type,NXUniqueString(PROP)))
return audioView;
return [super inspectorForType:type];
}
///////////////////////////////////
- editName:sender
{
[etAudio setAudioName:[sender stringValue]];
return self;
}
- erase:sender
{
if (![etAudio isAudioMutable]) {
NXRunAlertPanel( "eTAudio",
"You cannot modify the sound file %s. Try copying it "
"directly if you need to edit it.", NULL, NULL, NULL,
[etAudio audioName]);
return self;
}
[soundView stop:self];
[soundMeter stop:self];
if ([etAudio respondsTo:@selector(audioEnded)])
[etAudio audioEnded];
[soundView setSelection:0 size:[[etAudio sound] sampleCount]];
[soundView delete:self];
[playButton setState:0];
[recordButton setState:0];
[pauseButton setState:0];
[[audioView window] display];
return self;
}
- pause:sender
{
switch ([[soundView soundBeingProcessed] status]) {
case NX_SoundPlaying:
case NX_SoundRecording:
[soundView pause:self];
if ([etAudio respondsTo:@selector(audioPaused)])
[etAudio audioPaused];
break;
case NX_SoundPlayingPaused:
case NX_SoundRecordingPaused:
[soundView resume:self];
if ([etAudio respondsTo:@selector(audioResumed)])
[etAudio audioResumed];
break;
default: [pauseButton setState:0];
}
return self;
}
- play:sender
{
if ([[soundView soundBeingProcessed] status] == NX_SoundPlaying) {
[self stop:sender];
return self;
}
if( [[soundView soundBeingProcessed] duration]== 0.0) {
[playButton setState:0];
if ([etAudio respondsTo:@selector(audioEnded)])
[etAudio audioEnded];
return self;
}
[recordButton setState:0];
[pauseButton setState:0];
[soundView play:self];
[soundMeter setSound:[soundView soundBeingProcessed]];
if ([soundMeter window]) [soundMeter run:self];
if ([etAudio respondsTo:@selector(audioStarted)])
[etAudio audioStarted];
return self;
}
- record:sender
{
if (![etAudio isAudioMutable]) {
NXRunAlertPanel( "eTAudio",
"You cannot modify the sound file %s. Try copying "
"it directly if you need to edit it.", NULL, NULL, NULL,
[etAudio audioName]);
[recordButton setState:0];
if ([etAudio respondsTo:@selector(audioEnded)])
[etAudio audioEnded];
return nil;
}
if ([[soundView soundBeingProcessed] status] == NX_SoundRecording) {
[self stop:sender];
return self;
}
[playButton setState:0];
[pauseButton setState:0];
[soundView record:self];
[soundMeter setSound:[soundView soundBeingProcessed]];
[soundMeter run:self];
if ([etAudio respondsTo:@selector(audioStarted)])
[etAudio audioStarted];
return self;
}
- stop:sender
{
[playButton setState:0];
[recordButton setState:0];
[pauseButton setState:0];
[soundView stop:self];
[audioView display];
[soundMeter stop:self];
if ([etAudio respondsTo:@selector(audioEnded)])
[etAudio audioEnded];
return self;
}
- didPlay:sender {
[soundMeter stop:self];
[playButton setState:0];
[recordButton setState:0];
[pauseButton setState:0];
[[audioView window] display];
if ([etAudio respondsTo:@selector(audioEnded)])
[etAudio audioEnded];
return self;
}
- didRecord:sender {
[soundMeter stop:self];
[playButton setState:0];
[recordButton setState:0];
[pauseButton setState:0];
if ([etAudio respondsTo:@selector(audioEnded)])
[etAudio audioEnded];
return self;
}
- hadError:sender {return [stopButton performClick:self];}
- soundDidChange:sender {return [[etAudio etDoc] touch];}
/////////////////////////////////
- click:sender
{
if (sender != etAudio) return nil;
if (![soundView soundBeingProcessed])
[soundView setSound:[etAudio sound]];
switch ([soundView soundBeingProcessed] ?
[[soundView soundBeingProcessed] status] :
[[soundView sound] status]) {
case NX_SoundStopped: [playButton performClick:sender]; break;
case NX_SoundPlayingPaused:
case NX_SoundRecordingPaused:
case NX_SoundPlaying:
case NX_SoundRecording: [pauseButton performClick:sender]; break;
}
return self;
}
- doubleClick:sender
{
if (sender != etAudio) return nil;
return [stopButton performClick:self];
}
@end
@interface eTSoundMeter:SoundMeter
{}
- drawCurrentValue;
@end
@implementation eTSoundMeter
- drawCurrentValue{if (window) return [super drawCurrentValue]; return self;}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.