|
|
1.1 ! root 1: /* ! 2: * You may freely copy, distribute and reuse the code in this example. ! 3: * NeXT disclaims any warranty of any kind, expressed or implied, as to ! 4: * its fitness for any particular use. ! 5: */ ! 6: ! 7: ! 8: #import "SoundController.h" ! 9: #import "SaveToController.h" ! 10: #import "SoundDocument.h" ! 11: #import <soundkit/soundkit.h> ! 12: #import <appkit/Application.h> ! 13: #import <appkit/OpenPanel.h> ! 14: #import <appkit/Cursor.h> ! 15: #import <appkit/Button.h> ! 16: #import <appkit/Panel.h> ! 17: #import <appkit/publicWraps.h> /* for NXBeep() */ ! 18: #import <sys/param.h> /* for MAXPATHLEN */ ! 19: #import <string.h> ! 20: #import <objc/NXStringTable.h> ! 21: ! 22: static char pathname[1024]; ! 23: ! 24: static BOOL getOpenPath(char *buf, char const *theType) ! 25: { ! 26: static id openPanel = nil; ! 27: char const *fileTypes[2] = {0,0}; ! 28: int opr; ! 29: ! 30: if (!openPanel) ! 31: openPanel = [OpenPanel new]; ! 32: if (theType && *theType) ! 33: fileTypes[0] = theType; ! 34: [NXApp setAutoupdate:NO]; ! 35: ! 36: if (*buf) ! 37: opr = [openPanel runModalForDirectory:buf ! 38: file:NULL types:fileTypes]; ! 39: else ! 40: opr = [openPanel runModalForDirectory:"/NextLibrary/Sounds" ! 41: file:"Basso.snd" types:fileTypes]; ! 42: if (opr) { ! 43: strcpy(buf,[openPanel filename]); ! 44: [NXApp setAutoupdate:YES]; ! 45: return YES; ! 46: } else { ! 47: [NXApp setAutoupdate:YES]; ! 48: return NO; ! 49: } ! 50: } ! 51: ! 52: ! 53: static BOOL getSavePath(char *buf, char const *defaultPath, View *accessory) ! 54: { ! 55: static id savePanel = nil; ! 56: BOOL ok; ! 57: char dirName[1024], fileName[256]; ! 58: ! 59: if (!savePanel) { ! 60: const char *const types[2] = {"snd", NULL}; ! 61: savePanel = [SavePanel new]; ! 62: [savePanel setRequiredFileType:types[0]]; ! 63: } ! 64: [savePanel setAccessoryView:accessory]; ! 65: [NXApp setAutoupdate:NO]; ! 66: if (defaultPath && *defaultPath) { ! 67: char *p; ! 68: strcpy(dirName,defaultPath); ! 69: if (p = rindex(dirName,'/')) { ! 70: strcpy(fileName, p+1); ! 71: *p = '\0'; ! 72: } else { ! 73: strcpy(fileName,defaultPath); ! 74: fileName[0] = '\0'; ! 75: } ! 76: ok = [savePanel runModalForDirectory:dirName file:fileName]; ! 77: } else ! 78: ok = [savePanel runModal]; ! 79: [NXApp setAutoupdate:YES]; ! 80: if (ok) { ! 81: strcpy(buf,[savePanel filename]); ! 82: return YES; ! 83: } else ! 84: return NO; ! 85: } ! 86: ! 87: ! 88: @implementation SoundController ! 89: ! 90: - init ! 91: { ! 92: [super init]; ! 93: [controlPanel removeFromEventMask:(NX_KEYDOWNMASK|NX_KEYUPMASK)]; ! 94: [controlPanel setFloatingPanel:YES]; ! 95: return self; ! 96: } ! 97: ! 98: - appDidInit:sender ! 99: { ! 100: [self newSoundDoc:self]; /* User Interface guidelines recommend opening ! 101: a new document at launch time. We do this in ! 102: appDidInit: rather than init to make sure that ! 103: the stringTable has been unarchived */ ! 104: return self; ! 105: } ! 106: ! 107: - info:sender ! 108: { ! 109: if (!infoPanel) ! 110: [NXApp loadNibSection:"InfoPanel.nib" owner:self]; ! 111: [infoPanel orderFront:self]; ! 112: return self; ! 113: } ! 114: ! 115: - newSoundDoc:sender ! 116: { ! 117: static char filenamebuf[MAXPATHLEN+1]; ! 118: strcpy(filenamebuf, [[OpenPanel new] directory]); ! 119: /* doesn't instantiate a new OpenPanel ! 120: if one already exists */ ! 121: strcat(filenamebuf,[stringTable valueForStringKey:"/UNTITLED"]); ! 122: [self setDocument:[[SoundDocument alloc] init]]; ! 123: [currentDocument setFileName:filenamebuf]; ! 124: return self; ! 125: } ! 126: ! 127: ! 128: - setDocument:aDocument ! 129: { ! 130: [self stop:nil]; ! 131: currentDocument = aDocument; ! 132: [recordButton setEnabled:([currentDocument isRecordable]? YES : NO)]; ! 133: [playButton setEnabled:YES]; ! 134: [currentDocument setDelegate:self]; ! 135: return self; ! 136: } ! 137: ! 138: - document ! 139: { ! 140: return currentDocument; ! 141: } ! 142: ! 143: - openFile:(char *)fileName ! 144: { ! 145: id newDocument; ! 146: newDocument = [[SoundDocument alloc] init]; ! 147: [newDocument setFileName:fileName]; ! 148: [newDocument load:nil]; ! 149: [self setDocument:newDocument]; ! 150: return self; ! 151: } ! 152: ! 153: - open:sender ! 154: { ! 155: if (getOpenPath(pathname,"snd")) ! 156: [self openFile:pathname]; ! 157: return self; ! 158: } ! 159: ! 160: - saveAs:sender withAccessory:accessory ! 161: { ! 162: char pathname[1024]; ! 163: id doc = currentDocument; ! 164: if (accessory) ! 165: [saveToController setSound:[doc sound]]; ! 166: if (doc && getSavePath(pathname,[doc fileName],accessory)) { ! 167: if (accessory) ! 168: [doc saveToFormat:[saveToController soundTemplate] ! 169: fileName: pathname]; ! 170: else { ! 171: [doc setFileName:pathname]; ! 172: [doc save:sender]; ! 173: } ! 174: } ! 175: return self; ! 176: } ! 177: ! 178: - saveAs:sender ! 179: { ! 180: return [self saveAs:sender withAccessory:nil]; ! 181: } ! 182: ! 183: - saveTo:sender ! 184: { ! 185: return [self saveAs:sender withAccessory:saveToAccessoryView]; ! 186: } ! 187: ! 188: - save:sender ! 189: { ! 190: if (currentDocument) { ! 191: if ([currentDocument fileName] ! 192: && strcmp(strrchr([currentDocument fileName],'/'),"/UNTITLED")) ! 193: [currentDocument save:sender]; ! 194: else ! 195: [self saveAs:sender]; ! 196: } ! 197: return self; ! 198: } ! 199: ! 200: - revertToSaved:sender ! 201: { ! 202: if (currentDocument) ! 203: [currentDocument revertToSaved:sender]; ! 204: return self; ! 205: } ! 206: ! 207: - play:sender ! 208: { ! 209: if (![currentDocument isPlayable]) { ! 210: NXBeep(); ! 211: return nil; ! 212: } ! 213: if (currentDocument) { ! 214: [playButton setEnabled:NO]; ! 215: [recordButton setEnabled:NO]; ! 216: [stopButton setEnabled:YES]; ! 217: [pauseButton setState:0]; ! 218: [currentDocument play:sender]; ! 219: } ! 220: return self; ! 221: } ! 222: ! 223: - willPlay:sender ! 224: { ! 225: [meter setSound:[sender soundBeingProcessed]]; ! 226: [meter run:self]; ! 227: return self; ! 228: } ! 229: ! 230: - didPlay:sender ! 231: { ! 232: [playButton setState:0]; ! 233: [playButton setEnabled:YES]; ! 234: [recordButton setState:0]; ! 235: [recordButton setEnabled:YES]; ! 236: [pauseButton setState:0]; ! 237: [meter stop:self]; ! 238: return self; ! 239: } ! 240: ! 241: - stop:sender ! 242: { ! 243: if (currentDocument) ! 244: [currentDocument stop:sender]; ! 245: [playButton setState:0]; ! 246: [playButton setEnabled:YES]; ! 247: [recordButton setState:0]; ! 248: [recordButton setEnabled:YES]; ! 249: [pauseButton setState:0]; ! 250: return self; ! 251: } ! 252: ! 253: - pause:sender ! 254: { ! 255: if (!currentDocument || (![playButton state] && ![recordButton state])) { ! 256: [pauseButton setState:0]; ! 257: return self; ! 258: } else if ([pauseButton state]) ! 259: [currentDocument pause:self]; ! 260: else ! 261: [currentDocument resume:self]; ! 262: return self; ! 263: } ! 264: ! 265: - record:sender ! 266: { ! 267: if (currentDocument) { ! 268: [recordButton setEnabled:NO]; ! 269: [playButton setEnabled:NO]; ! 270: [stopButton setEnabled:YES]; ! 271: [currentDocument record:sender]; ! 272: } ! 273: return self; ! 274: } ! 275: ! 276: - willRecord:sender ! 277: { ! 278: [meter setSound:[sender soundBeingProcessed]]; ! 279: [meter run:self]; ! 280: return self; ! 281: } ! 282: ! 283: - didRecord:sender ! 284: { ! 285: [playButton setState:0]; ! 286: [playButton setEnabled:YES]; ! 287: [recordButton setState:0]; ! 288: [recordButton setEnabled:YES]; ! 289: [pauseButton setState:0]; ! 290: [meter stop:self]; ! 291: return self; ! 292: } ! 293: ! 294: - soundDidChange:sender ! 295: { ! 296: if (currentDocument) ! 297: [currentDocument touch]; ! 298: return self; ! 299: } ! 300: ! 301: - hadError:sender ! 302: { ! 303: int err = [[sender soundBeingProcessed] processingError]; ! 304: ! 305: if ([playButton state]) ! 306: NXRunAlertPanel([stringTable valueForStringKey:"Play error"], ! 307: SNDSoundError(err), ! 308: [stringTable valueForStringKey:"OK"], ! 309: NULL,NULL); ! 310: else if ([recordButton state]) ! 311: NXRunAlertPanel([stringTable valueForStringKey:"Record error"], ! 312: SNDSoundError(err), ! 313: [stringTable valueForStringKey:"OK"], ! 314: NULL,NULL); ! 315: return [self stop:self]; ! 316: } ! 317: ! 318: - appDidHide:sender ! 319: { ! 320: [self stop:nil]; ! 321: return self; ! 322: } ! 323: ! 324: - appDidBecomeActive:sender ! 325: { ! 326: [controlPanel orderFront:nil]; ! 327: return self; ! 328: } ! 329: ! 330: - stringTable ! 331: { ! 332: return stringTable; ! 333: } ! 334: ! 335: @end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.