This is ElementController.m in view mode; [Download] [Up]
/************************************************** * SynthBuilder * Copyright 1993 Nick Porcaro All Rights Reserved **************************************************/ #import <stdlib.h> #import <string.h> #import <objc/List.h> #import <appkit/Application.h> #import <appkit/Panel.h> #import <appkit/Control.h> #import <appkit/OpenPanel.h> #import <appkit/SavePanel.h> #import "ViewController.h" #import "DragView.h" #import "UGDef.h" #import "UGMethodDef.h" #import "UGArgDef.h" #import "NGDef.h" #import "NGArgDef.h" #import "NFDef.h" #import "NFMethodDef.h" #import "NFArgDef.h" #import "Controller.h" #import "Utilities.h" #import "ElementController.h" extern id savePanel; extern id openPanel; extern char *getSavePath(char *banner); extern char *getOpenPath(char *banner); extern char *getAppName(); @implementation ElementController static char TempString[1024]; - awakeFromNib { if (! theViewController) { theViewController = [[ViewController alloc] init]; [theViewController setMultiView:theMultiView]; [theViewController setDragView:theDragView]; [theViewController setFocusLock:NO]; } [theDragView setViewController:theViewController]; if (! theUGList) { theUGList = [[List alloc] init]; } if (! theNFList) { theNFList = [[List alloc] init]; } if (! theNGList) { theNGList = [[List alloc] init]; } // Only do this to bootstrap [self buildStandardUGDefs]; [self readStandardDefs]; [theViewController switchViewToNumber:1]; [theController displayMainWindow]; [theViewController setFocusLock:YES]; return self; } - init { [super init]; return self; } - switchView:sender { [theViewController switchView:sender]; return self; } - displayInspector:sender { [theViewController displayInspector:sender]; return self; } - readStandardDefs { [self readStandardUGDefs:self]; [self readStandardNGDefs:self]; [self readStandardNFDefs:self]; return self; } - readStandardUGDefs:sender { int len; char *dir; char *path; if ( ! (dir = [utilities getAppDir])) { return self; } len = strlen(dir) + 100; path = (char *) NXZoneCalloc([self zone], len, sizeof(char)); sprintf(path, "%s/StandardUGDefs", dir); [self readUGDefs:path]; NXZoneFree([self zone], path); return self; } - readStandardNGDefs:sender { int len; char *dir; char *path; if ( ! (dir = [utilities getAppDir])) { return self; } len = strlen(dir) + 100; path = (char *) NXZoneCalloc([self zone], len, sizeof(char)); sprintf(path, "%s/StandardNGDefs", dir); [self readNGDefs:path]; NXZoneFree([self zone], path); return self; } - readStandardNFDefs:sender { int len; char *dir; char *path; if ( ! (dir = [utilities getAppDir])) { return self; } len = strlen(dir) + 100; path = (char *) NXZoneCalloc([self zone], len, sizeof(char)); sprintf(path, "%s/StandardNFDefs", dir); [self readNFDefs:path]; NXZoneFree([self zone], path); return self; } - setUGList: aUGList { theUGList = aUGList; return self; } - setNGList: aNGList { theNGList = aNGList; return self; } - setNFList: aNFList { theNFList = aNFList; return self; } - getUGList { return theUGList; } - getNGList { return theNGList; } - getNFList { return theNFList; } - initViews /* Call setNGList/setNFList/setUGList first */ { [self initUGView]; [self initNFView]; [self initNGView]; return self; } - initUGView { [theViewController initView: 1 list: theUGList class: [UGDef class] name: "Unit Generators"]; return self; } - initNGView { [theViewController initView: 2 list: theNGList class: [NGDef class] name: "Note Generators"]; return self; } - initNFView { [theViewController initView: 3 list: theNFList class: [NFDef class] name: "Note Filters"]; return self; } /************ This monster was the original way that ************ "FakeUGs" were defined in the old program ****************************************************/ #define MAXCONNECTIONS 5 #define MAXNOTEPARAMETERS 9 /* The number of rows in the FakeUG inspector also */ #define MK_UG 0 #define CLM_UG 1 #define PP_UG 2 // A PatchParameter #define CLAV_UG 3 // A clavier #define MIDI_UG 4 // A midi input #define NF_UG 5 // A note filter (users should be able to add these) #define INT 0 #define DOUBLE 1 #define ENV 2 #define BOOLEAN 3 #define DSPDATUM 4 #define PARTIALS 5 typedef struct { char *niceName; char *type; int ugType; // Type of UG char *iconName; BOOL isEnvelopeHandler; BOOL isADSwitch; BOOL isData; BOOL isOscg; BOOL isSineROM; BOOL hasLength; BOOL hasConstant; BOOL isStorage; struct { char *methodName; int x; int y; BOOL isOutput; } connection[MAXCONNECTIONS]; struct { char *methodName; int argType; char *defaultArgValue; } noteParameters[MAXNOTEPARAMETERS]; } oldFakeUGInfoType; /* The first connection is for the output. */ /* * The methods are in order that the corresponding memory segments are in * in the name of the include file. */ /* * Also, synthdata, and the relevant memory issues, have not been handled * yet, i.e. for delay, Oscgaf, and Oscgafi. */ const oldFakeUGInfoType oldFakeUGInfo[] = { /*************************************** Explanation of initialization for AllPass1UG: type = Allpass1UG iconName = allpass1 isEnvelopeHandler = isADSwitch = isData = isOscg = isSineROM = hasLength = hasConstant = NO connection struct: methodName1 = setOutput: x1 = 28 x2 = 15 methodName2 = setInput: x1 = 28 x2 = 15 noteParameters struct: methodName1 = setBB0 argType1 = DOUBLE defaultArgValue = "0" The number of connection and noteParameters is obtainable by finding out how many are non-NULL ***********************************/ {"Allpass Filter", "Allpass1UG", MK_UG, "allpass1", NO, NO, NO, NO, NO, NO, NO, NO, {{"setOutput:", 28, 15, YES}, {"setInput:", 28, 42, NO}}, {{"setBB0:", DOUBLE, "0"}} }, {"Add2", "Add2UG", MK_UG, "add2", NO, NO, NO, NO, NO, NO, NO, NO, {{"setOutput:", 28, 15, YES}, {"setInput1:", 15, 42, NO}, {"setInput2:", 40, 42, NO}}, {} }, {"Envelope", "AsympUG", MK_UG, "asymp", YES, NO, NO, NO, NO, NO, NO, NO, {{"setOutput:", 28, 15, YES}}, {{"setRate:", DOUBLE, "0"}, {"setReleaseXScale:", DOUBLE, "0"}, {"setTargetVal:", DOUBLE, "0"}, {"setT60:", DOUBLE, "0"}, {"setEnvelope: ...", ENV, ""}} }, {"Constant", "ConstantUG", MK_UG, "constant", NO, NO, NO, NO, NO, NO, NO, NO, {{"setOutput:", 28, 15, YES}}, {{"setConstant:", DOUBLE, "1.00"}} }, {"Delay", "DelayUG", MK_UG, "delay", NO, NO, NO, NO, NO, NO, NO, NO, {{"setOutput:", 51, 28, YES}, {"setInput:", 3, 28, NO}, {"setDelayMemory:", 27, 28, NO}}, {{"adjustLength:", INT, "0"}} }, {"Dswitch", "DswitchUG", MK_UG, "dswitch", NO, YES, NO, NO, NO, NO, NO, NO, {{"setOutput:", 28, 15, YES}, {"setInput1:", 15, 42, NO}, {"setInput2:", 40, 42, NO}}, {{"setDelaySamples:", INT, "0"}, {"setScale1:", DOUBLE, "0"}} }, {"Dswitcht", "DswitchtUG", MK_UG, "dswitcht", NO, YES, NO, NO, NO, NO, NO, NO, {{"setOutput:", 28, 15, YES}, {"setInput1:", 15, 42, NO}, {"setInput2:", 40, 42, NO}}, {{"setDelayTicks:", INT, "0"}, {"setScale1:", DOUBLE, "0"}, {"setScale2:", DOUBLE, "0"}} }, {"Interpolator", "InterpUG", MK_UG, "interp", NO, NO, NO, NO, NO, NO, NO, NO, {{"setOutput:", 28, 15, YES}, {"setInput1:", 17, 42, NO}, {"setInput2:", 36, 42, NO}, {"setInterpInput:", 26, 42, NO}}, {} }, {"Mult/add2", "Mul1add2UG", MK_UG, "mul1add2", NO, NO, NO, NO, NO, NO, NO, NO, {{"setOutput:", 28, 15, YES}, {"setInput1:", 15, 42, NO}, {"setInput2:", 27, 42, NO}, {"setInput3:", 40, 42, NO}}, {} }, {"Mult2", "Mul2UG", MK_UG, "mul2", NO, NO, NO, NO, NO, NO, NO, NO, {{"setOutput:", 28, 15, YES}, {"setInput1:", 15, 42, NO}, {"setInput2:", 40, 42, NO}}, {} }, {"One pole filter", "OnepoleUG", MK_UG, "onepole", NO, NO, NO, NO, NO, NO, NO, NO, {{"setOutput:", 28, 15, YES}, {"setInput:", 28, 42, NO}}, {{"setA1:", DOUBLE, "0"}, {"setB0:", DOUBLE, "0"}} }, {"One zero filter", "OnezeroUG", MK_UG, "onepole", NO, NO, NO, NO, NO, NO, NO, NO, {{"setOutput:", 28, 15, YES}, {"setInput:", 28, 42, NO}}, {{"setB0:", DOUBLE, "0"}, {"setB1:", DOUBLE, "0"}} }, {"Osc", "OscgUG", MK_UG, "oscg", NO, NO, NO, YES, NO, NO, NO, NO, {{"setOutput:", 27, 15, YES}, {"setTable:", 27, 29, NO}}, {{"setInc:", INT, "0"}, {"setFreq:", DOUBLE, "440.0"}, {"setAmp:", DOUBLE, "0.5"}, {"setPhase:", DOUBLE, "0.0"}} }, {"Osc freq/amp", "OscgafUG", MK_UG, "oscgaf", NO, NO, NO, YES, NO, NO, NO, NO, {{"setOutput:", 27, 15, YES}, {"setAmpInput:", 17, 43, NO}, {"setIncInput:", 42, 43, NO}, {"setTable:", 27, 29, NO}}, {{"setIncScaler:", INT, "0"}, /* checked */ {"setPhase:", DOUBLE, "0"}, /* checked */ {"setIncRatio:", DOUBLE, "1.0"}} }, {"Osc interp/freq/amp", "OscgafiUG", MK_UG, "oscgafi", NO, NO, NO, YES, NO, NO, NO, NO, {{"setOutput:", 27, 15, YES}, {"setAmpInput:", 17, 43, NO}, {"setIncInput:", 42, 43, NO}, {"setTable:", 27, 29, NO}}, {{"setIncScaler:", INT, "0"}, {"setPhase:", DOUBLE, "0"}, {"setIncRatio:", DOUBLE, "1.0"}} }, {"Speaker A", "Out1aUG", MK_UG, "out1a", NO, NO, NO, NO, NO, NO, NO, NO, {{"setInput:", 28, 48, NO}}, {{"setScale:", DOUBLE, "1.0"}} }, {"Speaker B", "Out1bUG", MK_UG, "out1b", NO, NO, NO, NO, NO, NO, NO, NO, {{"setInput:", 28, 48, NO}}, {{"setScale:", DOUBLE, "1.0"}} }, {"Stereo Out", "Out2sumUG", MK_UG, "out2sum", NO, NO, NO, NO, NO, NO, NO, NO, {{"setInput:", 28, 48, NO}}, {{"setBearing:", DOUBLE, "0"}, /* checked */ {"setLeftScale:", DOUBLE, "1.0"}, /* checked */ {"setRightScale:", DOUBLE, "1.0"}} }, {"Scale", "ScaleUG", MK_UG, "scale", NO, NO, NO, NO, NO, NO, NO, NO, {{"setOutput:", 51, 28, YES}, {"setInput:", 3, 28, NO}}, {{"setScale:", DOUBLE, "1.0"}} }, {"Scale add2", "Scl1add2UG", MK_UG, "scl1add2", NO, NO, NO, NO, NO, NO, NO, NO, {{"setOutput:", 28, 15, YES}, {"setInput1:", 15, 42, NO}, {"setInput2:", 40, 42, NO}}, {{"setScale:", DOUBLE, "1.0"}} }, {"Scale2 add2", "Scl2add2UG", MK_UG, "scl2add2", NO, NO, NO, NO, NO, NO, NO, NO, {{"setOutput:", 28, 15, YES}, {"setInput1:", 15, 42, NO}, {"setInput2:", 40, 42, NO}}, {{"setScale1:", DOUBLE, "1.0"}, {"setScale2:", DOUBLE, "1.0"}} }, {"S Noise", "SnoiseUG", MK_UG, "snoise", NO, NO, NO, NO, NO, NO, NO, NO, {{"setOutput:", 27, 15, YES}}, {} }, {"U Noise", "UnoiseUG", MK_UG, "unoise", NO, NO, NO, NO, NO, NO, NO, NO, {{"setOutput:", 27, 15, YES}}, {} }, {"Constant PatchPoint", "Constantpp", MK_UG, "constantpp", NO, NO, YES, NO, NO, NO, YES, NO, {{"", 27, 29, YES}}, {{"setToConstant", DSPDATUM, "1.0"}} }, {"Partials", "Partials", MK_UG, "partials", NO, NO, YES, NO, NO, YES, NO, NO, {{"", 27, 29, YES}}, {{"length", INT, "0"}, {"partials", PARTIALS, "0"}} }, {"Sine ROM", "SineROM", MK_UG, "sinerom", NO, NO, YES, NO, YES, NO, NO, NO, {{"", 27, 29, YES}}, {} }, {"Memory", "Storage", MK_UG, "storage", NO, NO, YES, NO, NO, YES, YES, YES, {{"", 27, 29, YES}}, {{"length:", INT, "300"}, {"setToConstant:", DSPDATUM, "1000"}} }, {"Table Lookup", "TablookUG", MK_UG, "tablelookup", NO, NO, NO, NO, NO, NO, NO, NO, {{"setOutputAout:", 27, 15, YES}, // the output is on the bottom. {"setInputAinv:", 27, 42, NO}, // the input is on the top. {"setAddressAtablook:",27, 30, NO}}, // the table is the center one {{"setTableSize:", INT, "0"}} }, {"Digital In A", "In1aUG", MK_UG, "in1a", NO, NO, NO, NO, NO, NO, NO, NO, {{"setOutput:", 28, 15, YES}}, {{"setScale:", DOUBLE, "1.0"}} }, {"Digital In B", "In1bUG", MK_UG, "in1b", NO, NO, NO, NO, NO, NO, NO, NO, {{"setOutput:", 28, 15, YES}}, {{"setScale:", DOUBLE, "1.0"}} }, {"Biquad filter", "BiquadUG", MK_UG, "biquad", NO, NO, NO, NO, NO, NO, NO, NO, {{"setOutput:", 28, 15, YES}, {"setInput:", 28, 42, NO}}, { {"setA1:", DOUBLE, "0.5"}, {"setA2:", DOUBLE, "0.5"}, {"setB1:", DOUBLE, "0.5"}, {"setB2:", DOUBLE, "0.5"}, {"setComplexPolesRadius:", DOUBLE, "0.5"}, /* Sorry only one argument for now */ {"setComplexZerosRadius:", DOUBLE, "0.5"}, /* Sorry only one argument for now */ {"setComplexPolesFrequency:", DOUBLE, "0.5"}, /* Sorry only one argument for now */ {"setComplexZerosFrequency:", DOUBLE, "0.5"}, /* Sorry only one argument for now */ {"setGain:", DOUBLE, "1.0"}, /* I hope the default is reasonable */ {"setFirstDelayedSample:", DOUBLE, "0"}, /* I hope the default is reasonable */ {"setSecondDelayedSample:", DOUBLE, "0"} /* I hope the default is reasonable */ } }, {"Patch Parameter", "PatchParameter", PP_UG, "PatchParameter", NO, NO, NO, NO, NO, NO, NO, NO, {{"setInput:", 28, 42, NO}}, {} }, {"Clavier", "Clavier", CLAV_UG, "Clavier", NO, NO, NO, NO, NO, NO, NO, NO, {{"setOutput:", 28, 15, YES}}, {} }, {"MIDI IN-A", "MIDI-A", MIDI_UG, "MIDI-A", NO, NO, NO, NO, NO, NO, NO, NO, {{"setOutput:", 28, 15, YES}}, {} }, {"MIDIIN-B", "MIDI-B", MIDI_UG, "MIDI-B", NO, NO, NO, NO, NO, NO, NO, NO, {{"setOutput:", 28, 15, YES}}, {} } }; #define NUM_UG_DEFS sizeof(oldFakeUGInfo)/sizeof(oldFakeUGInfoType) - buildStandardUGDefs /* This is legacy code that hopefully can go away real soon! * Call setUGList first */ { int i, j; id aDef, aMethod, anArg; for (i=0; i<NUM_UG_DEFS; i++) { if (oldFakeUGInfo[i].ugType == MK_UG) { aDef = [[UGDef alloc] init]; [theUGList addObject:aDef]; [aDef setMetaType:MK_UG]; [aDef setNibFile:"FakeUG.nib"]; /* Change if you dare */ } else if (oldFakeUGInfo[i].ugType == PP_UG) { aDef = [[UGDef alloc] init]; [theNFList addObject:aDef]; [aDef setMetaType:PP_UG]; [aDef setNibFile:"PatchParam.nib"]; [aDef setIsPatchParameter:YES]; } else if (oldFakeUGInfo[i].ugType == NF_UG) { aDef = [[UGDef alloc] init]; [theNFList addObject:aDef]; [aDef setMetaType:NF_UG]; [aDef setNibFile:"NoteFilter.nib"]; [aDef setIsNoteFilter:YES]; } else if (oldFakeUGInfo[i].ugType == MIDI_UG) { aDef = [[UGDef alloc] init]; [theNGList addObject:aDef]; [aDef setMetaType:MIDI_UG]; [aDef setNibFile:""]; [aDef setIsMidi:YES]; } else if (oldFakeUGInfo[i].ugType == CLAV_UG) { aDef = [[UGDef alloc] init]; [theNGList addObject:aDef]; [aDef setMetaType:CLAV_UG]; [aDef setNibFile:"Clavier.nib"]; [aDef setIsClavier:YES]; } else { aDef = nil; printf("barf fart splat\n"); } [(UGDef *) aDef setName:oldFakeUGInfo[i].niceName]; [aDef setTheType:oldFakeUGInfo[i].type]; [aDef setIconFile:oldFakeUGInfo[i].iconName]; [aDef setIsEnvelopeHandler:oldFakeUGInfo[i].isEnvelopeHandler]; [aDef setIsADSwitch:oldFakeUGInfo[i].isADSwitch]; [aDef setIsData:oldFakeUGInfo[i].isData]; [aDef setIsOscg:oldFakeUGInfo[i].isOscg]; [aDef setIsSineROM:oldFakeUGInfo[i].isSineROM]; [aDef setHasLength:oldFakeUGInfo[i].hasLength]; [aDef setHasConstant:oldFakeUGInfo[i].hasConstant]; [aDef setIsStorage:oldFakeUGInfo[i].isStorage]; for (j=0; j<MAXCONNECTIONS; j++) { if (oldFakeUGInfo[i].connection[j].methodName) { aMethod = [aDef addNewMethod:oldFakeUGInfo[i].connection[j].methodName]; [aMethod setIsOutput:oldFakeUGInfo[i].connection[j].isOutput]; [aMethod setXCoord:oldFakeUGInfo[i].connection[j].x]; [aMethod setYCoord:oldFakeUGInfo[i].connection[j].y]; } } for (j=0; j<MAXNOTEPARAMETERS; j++) { if (oldFakeUGInfo[i].noteParameters[j].methodName) { anArg = [aDef addNewArg:oldFakeUGInfo[i].noteParameters[j].methodName]; [anArg setArgType:oldFakeUGInfo[i].noteParameters[j].argType]; [anArg setDefaultValue:oldFakeUGInfo[i].noteParameters[j].defaultArgValue]; } } printf("Added: %s icon: %s (index: %d)\n", [aDef getName], [aDef getIconFile], i); } return self; } - oldUGTypeToUGDef: (int) old_index /* This converts an index into the old table * into a UGDef. It does this by getting the type * name corresponding to old_index from theUGList */ { char *old_type; int i; if (old_index >= NUM_UG_DEFS) { NXRunAlertPanel(getAppName(), "Invalid index on attempt to convert", NULL, NULL, NULL); return nil; } if (! theUGList) { NXRunAlertPanel(getAppName(), "theUGList is nil", NULL, NULL, NULL); return nil; } old_type = oldFakeUGInfo[old_index].type; if (! old_type) { NXRunAlertPanel(getAppName(), "old_type is NULL", NULL, NULL, NULL); return nil; } for (i=0; i<[theUGList count]; i++) { if (strcmp(old_type, [[theUGList objectAt:i] getType]) == 0) { return [theUGList objectAt:i]; } } return nil; } - writeUGDefs:sender { char *file; sprintf(TempString, "%s Save Unit Generator Defs", getAppName()); file = getSavePath(TempString); if (! file) { return self; } [self writeDefsFrom:theUGList To:file]; return self; } - writeNFDefs:sender { char *file; sprintf(TempString, "%s Save Note Filter Defs", getAppName()); file = getSavePath(TempString); if (! file) { return self; } [self writeDefsFrom:theNFList To:file]; return self; } - writeNGDefs:sender { char *file; sprintf(TempString, "%s Save Note Generator Defs", getAppName()); file = getSavePath(TempString); if (! file) { return self; } [self writeDefsFrom:theNGList To:file]; return self; } - writeDefsFrom: aList To:(char *) aFile { NXTypedStream *ts; if (! aFile || ! aList) { return nil; } ts = NXOpenTypedStreamForFile(aFile, NX_WRITEONLY); NXWriteRootObject(ts, aList); NXCloseTypedStream(ts); return self; } - readUGDefsFromMenu:sender { char *file; file = getOpenPath("Load Unit Generators"); if (! file) { return self; } [self readUGDefs:file]; return self; } - readNGDefsFromMenu:sender { char *file; file = getOpenPath("Load Note Generators"); if (! file) { return self; } [self readNGDefs:file]; return self; } - readNFDefsFromMenu:sender { char *file; file = getOpenPath("Load Note Generators"); if (! file) { return self; } [self readNFDefs:file]; return self; } - readUGDefs:(char *) file { id aList; aList = [self readDefsFrom:file]; if (aList) { [theUGList freeObjects]; [theUGList free]; } theUGList = aList; [self initUGView]; [theViewController switchViewToNumber:1]; return self; } - readNGDefs:(char *) file { id aList; aList = [self readDefsFrom:file]; if (aList) { [theNGList freeObjects]; [theNGList free]; } theNGList = aList; [self initNGView]; [theViewController switchViewToNumber:2]; return self; } - readNFDefs:(char *) file { id aList; aList = [self readDefsFrom:file]; if (aList) { [theNFList freeObjects]; [theNFList free]; } theNFList = aList; [self initNFView]; [theViewController switchViewToNumber:3]; return self; } static int defCompare(const void *def1, const void *def2) { return strcmp([*(id *)def1 getName],[*(id *)def2 getName]); } - (List *) readDefsFrom: (char *) file { NXTypedStream *ts; List *aList = nil; if (! file) { return nil; } ts = NXOpenTypedStreamForFile(file, NX_READONLY); if (! ts) { sprintf(TempString, "Error cannot open file: %s", file); NXRunAlertPanel(getAppName(), TempString, NULL, NULL, NULL); return nil; } aList = NXReadObject(ts); NXCloseTypedStream(ts); if (! aList) { printf("ElementController nil list\n"); return nil; } else { /* Sort the List and return it */ [utilities sortList:aList sortFunction:defCompare]; return aList; } } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.