This is FakePatchPoint.m in view mode; [Download] [Up]
/************************************************** * SynthBuilder * Copyright 1993 Nick Porcaro All Rights Reserved **************************************************/ /* #define DEBUG_ERASE 1 */ /* * FakePatchPoint.m * Eric Jordan, independent work, Spring, 1992 */ #import <stdlib.h> #import <stdio.h> #import <appkit/Application.h> #import <appkit/Control.h> #import <appkit/Slider.h> #import <musickit/musickit.h> #import "FakePatchPoint.h" #import "FakeSynthPatch.h" #import "PatchParam.h" #import "Clavier.h" #import "FakeUG.h" #import <dsp/DSPConversion.h> #import "Utilities.h" extern char *getAppName(); @implementation FakePatchPoint static char TempString[1024]; + initialize /* Set the version. This can be used in a later version to distinguish older * formats when unarchiving documents. */ { [FakePatchPoint setVersion:3]; return self; } - awakeFromNib { clickCount = 0; midiConnected = NO; return self; } - init { [super init]; toNode = [[List alloc] init]; allocOrder = 1; isAllocated = NO; strcpy(theName,""); clickCount = 0; useInspectorRect = NO; inspectorRectJustLoaded = NO; midiConnected = NO; return self; } - setSP:aSP { theSP = aSP; return self; } - closeInspector { [inspector performClose:self]; inspectorDisplayed = NO; return self; } - setName:(char *) aName { if (! aName) { return nil; } if (! [[theSP utilities] checkName:aName]) { if (inspector) { [ppNameField setStringValue:theName]; } return nil; } strcpy(theName, aName); return self; } - takeAllocOrderFrom:sender { int button, order, ival, maxOrder; maxOrder = [[theSP getFakePatchPoints] count]; order = [self getAllocOrder]; if ([sender isKindOfClassNamed: "TextField"]) { ival = [sender intValue]; if ((ival <= maxOrder) && (ival >=1)) { [self setAllocOrder:order]; [theSP sortFakePatchPointsByAllocOrder]; [self updateAllocOrder]; } else { NXRunAlertPanel(getAppName(), "Invalid order: %d Must be between 1 and %d", NULL, NULL, NULL, ival, maxOrder); [sender setIntValue:order]; return self; } } else { /* Get order from switcher */ /* button = 1 for top, -1 for botton */ button = [[sender selectedCell] tag]; order += button; /* Only set a new order if it's within range */ if ((order <= maxOrder) && (order >= 1)) { [self setAllocOrder:order]; [theSP sortFakePatchPointsByAllocOrder]; [self updateAllocOrder]; } } return self; } - setAllocOrder:(int) order { allocOrder = order; return self; } - (int) getAllocOrder { return allocOrder; } - updateAllocOrder { [allocOrderField setIntValue:allocOrder]; return self; } - displayInspector { if (! inspector) { [NXApp loadNibSection:"FakePatchPoint.nib" owner:self withNames:NO]; } [ppNameField setStringValue:theName]; [self updateAllocOrder]; [self setInspectorName: theName]; [self updateInfo]; if (inspectorRectJustLoaded) { if (useInspectorRect) { [inspector placeWindowAndDisplay:&inspectorRect]; useInspectorRect = NO; } inspectorRectJustLoaded = NO; } /* doHighlight toggle prevents the instance * from being highlighted twice */ doHighlight = NO; [inspector makeKeyAndOrderFront:self]; doHighlight = YES; inspectorDisplayed = YES; return self; } - displayInspectorIfWasActive { if (inspectorDisplayed) { [self displayInspector]; } return self; } - updateInfo { int i; id aFakeUG, aToNode; static char fromStr[256], toStr[256]; char *ptr; int count; aFakeUG = [fromNode superview]; ptr = [aFakeUG getMethod:[fromNode getTag]]; if (ptr) { sprintf(fromStr, "%s %s", [aFakeUG getName], ptr); } else { sprintf(fromStr, "%s", [aFakeUG getName]); } [fromInfo setStringValue:fromStr]; strcpy(toStr, ""); count = [toNode count]; for (i=0; i<count; i++) { aToNode = [toNode objectAt:i]; aFakeUG = [aToNode superview]; ptr = [aFakeUG getMethod:[aToNode getTag]]; if (ptr) { sprintf(TempString, "%s %s", [aFakeUG getName], ptr); } else { sprintf(TempString, "%s", [aFakeUG getName]); } strcat(toStr, TempString); if (i < (count - 1)) { strcat(toStr, ", "); } } [toInfo setStringValue:toStr]; return self; } - inspectorClosed /* Called by the inspector's delegate */ { inspectorDisplayed = NO; return self; } - setInspectorName:(char *) aName { [inspector setTitle: aName]; return self; } - validate { int i; id aToNode; [fromNode setPatch: theSP]; for (i=0; i<[toNode count]; i++) { aToNode = [toNode objectAt:i]; [aToNode setPatch: theSP]; [self checkMidiFrom:[fromNode superview] To:[aToNode superview]]; } return self; } -connect:newFromNode to:newToNode xmemory:(BOOL)mem { id fromFakeUG, toFakeUG; fromFakeUG = [newFromNode superview]; toFakeUG = [newToNode superview]; if ( ([fromFakeUG isClavier] && [toFakeUG isPatchParameter])) { id nr; [[fromFakeUG clavier] connectNoteSenderTo: [[toFakeUG patchParam] noteReceiver]]; // This bologna is because we have to make sure noteOnHandler is last thing nr = [[[fromFakeUG clavier] noteOnHandler] noteReceiver]; [[[fromFakeUG clavier] noteSender] disconnect:nr]; [[[fromFakeUG clavier] noteSender] connect:nr]; } /* Make sure we don't connect event UGs to non-event UGs */ if ( ([fromFakeUG isClavier] && ! [toFakeUG isPatchParameter]) || ([fromFakeUG isMidi] && ! [toFakeUG isPatchParameter]) ) { return self; } if (! [self checkMidiFrom:fromFakeUG To:toFakeUG]) { return nil; } if (!fromNode) { fromNode = newFromNode; xmemory = mem; } [toNode addObject:newToNode]; return self; } - checkMidiFrom:aFromFakeUG To:aToFakeUG { id midi; // if ([aFromFakeUG isMidi] && [aToFakeUG isPatchParameter] && ! midiConnected) if ([aFromFakeUG isMidi] && [aToFakeUG isPatchParameter]) { id nr; if (! [theSP initMidi]) { return nil; } midi = [theSP midi]; [midi setMergeInput:YES]; // or [midi channelNoteSender:1] and no setMergeInput [[midi noteSender] connect:[[aToFakeUG patchParam] noteReceiver]]; nr = [[theSP midiNoteOnHandler] noteReceiver]; [[midi noteSender] disconnect:nr]; [[midi noteSender] connect:nr]; midiConnected = YES; } return self; } -(FakeUG *)getFromFakeUG { return [fromNode superview]; } -(int)getFromConnectionNumber { return [fromNode getTag]; } -getFromNode { return fromNode; } -getToNodes { return toNode; } -(BOOL)getXMemory { return xmemory; } -(char *)getName { return theName; } -getpp { return pp; } - takeNameFromInspector:sender { [self setName:(char *) [sender stringValue]]; [ppNameField setStringValue: [sender stringValue]]; [self setInspectorName: theName]; return self; } -(char *)getTypeString { if ([[fromNode superview] isData]) if (xmemory) return "xData"; else return "yData"; if (xmemory) return "xPatch"; else return "yPatch"; } -(BOOL)isAFakeUG { return NO; } -(BOOL)isAFakePatchPoint { return YES; } -(BOOL)isPatchParameter { return NO; } -(BOOL)isClavier { return NO; } -(BOOL)isMidi { return NO; } -allocatePPMK { int i; id toFakeUG; id fromFakeUG; id midi; if (isAllocated) { return self; } /* Nasty hack for putting Claviers/Midi/PatchParameter back together again */ fromFakeUG = [fromNode superview]; if ( [fromFakeUG isClavier] || [fromFakeUG isMidi]) { for (i=0; i<[toNode count]; i++) { toFakeUG = [[toNode objectAt:i] superview]; if ([ toFakeUG isPatchParameter]) { [[fromFakeUG clavier] connectNoteSenderTo: [[toFakeUG patchParam] noteReceiver]]; } else { midi = [fromFakeUG midi]; [midi connectNoteSenderTo: [[toFakeUG patchParam] noteReceiver]]; } } isAllocated = YES; } if (xmemory) { if ([[fromNode superview] isData]) { pp = [[superview getOrch] allocSynthData:MK_xData length:[[fromNode superview] getLength]]; isAllocated = YES; } else { pp = [[superview getOrch] allocPatchpoint:MK_xPatch]; isAllocated = YES; } } else { if ([[fromNode superview] isData]) { if (!([[fromNode superview] isSineROM])) { pp = [[superview getOrch] allocSynthData:MK_yData length:[[fromNode superview] getLength]]; isAllocated = YES; } } else { pp = [[superview getOrch] allocPatchpoint:MK_yPatch]; isAllocated = YES; } } if (! pp & ![[fromNode superview] isSineROM]) { NXRunAlertPanel(getAppName(), "Is DSP being used by another app? Could not allocate %s", NULL, NULL, NULL, [self getName]); isAllocated = NO; return nil; } if ([[fromNode superview] hasConstant]) { [pp setToConstant: DSPDoubleToFix24(atod([[fromNode superview] getConstant]))]; } return self; } -deallocPPMK { [pp finish]; [pp dealloc]; pp = nil; isAllocated = NO; return self; } -makeConnectionsMK { int i; if (!([[fromNode superview] isSineROM])) { [[[fromNode superview] getUG] perform:sel_getUid([[fromNode superview] getConnectionName:[fromNode getTag]]) with:pp]; for (i=0; i<[toNode count]; i++) { id node = [toNode objectAt:i]; [[[node superview] getUG] perform:sel_getUid([[node superview] getConnectionName:[node getTag]]) with:pp]; } } return self; } -eraseSelf { NXRect fromFrame, toFrame; int i; id fromFakeUG; double width; fromFakeUG = [fromNode superview]; #ifdef DEBUG_ERASE printf("(FakePatchPoint %s -eraseSelf)\n", [self getName], [fromFakeUG getName]); #endif DEBUG_ERASE for (i=0; i<[toNode count]; i++) { fromFrame = [fromNode frame]; toFrame = [[toNode objectAt:i] frame]; [[fromNode superview] convertRect:&fromFrame toView:self]; [[[toNode objectAt:i] superview] convertRect:&toFrame toView:self]; PSmoveto(fromFrame.origin.x+fromFrame.size.width/2, fromFrame.origin.y+fromFrame.size.height/2); PSlineto(toFrame.origin.x+toFrame.size.width/2, toFrame.origin.y+toFrame.size.height/2); PSsetgray(NX_LTGRAY); if ([fromFakeUG isClavier] || [fromFakeUG isMidi]) { width = 2*LINEWIDTH; } else { width = LINEWIDTH; } PSsetlinewidth(width); PSstroke(); NXPing(); } return self; } -removeSelf { int i; [self lockFocus]; [self eraseSelf]; [self unlockFocus]; [self closeInspector]; #ifdef DEBUG_ERASE printf("(FakePatchPoint %s - removeSelf) Attempting to remove connection %d on fromfakeUG: %s\n", [self getName], [fromNode getTag], [[fromNode superview] getName]); #endif DEBUG_ERASE /**** Old Way [[fromNode superview] remConnection:[fromNode getTag]]; *****************/ [[fromNode superview] nilConnectionsWithId:self]; for (i=0; i<[toNode count]; i++) { #ifdef DEBUG_ERASE printf("(FakePatchPoint %s - removeSelf) Attempting to remove connection %d on fromfakeUG: %s\n", [self getName], [[toNode objectAt:i] getTag], [[[toNode objectAt:i] superview] getName]); #endif DEBUG_ERASE /**** Old way [[[toNode objectAt:i] superview] remConnection: [[toNode objectAt:i] getTag]]; *****************/ [[[toNode objectAt:i] superview] nilConnectionsWithId:self]; } #ifdef DEBUG_ERASE printf("(FakePatchPoint %s - removeSelf) Attempting to remove 0x%x from list in %s\n", [self getName], self, [superview getName]); #endif DEBUG_ERASE [superview remFakePatchPointFromList:self]; return self; } -drawSelf:(const NXRect *)rects :(int)rectCount { int i; double gray, width; int x1, y1, x2, y2; NXRect fromFrame, toFrame; id fromFakeUG, toFakeUG; fromFakeUG = [fromNode superview]; for (i=0; i<[toNode count]; i++) { toFakeUG = [[toNode objectAt:i] superview]; if ((![fromFakeUG getErasing]) && (![toFakeUG getErasing])) { fromFrame = [fromNode frame]; toFrame = [[toNode objectAt:i] frame]; [fromFakeUG convertRect:&fromFrame toView:self]; [toFakeUG convertRect:&toFrame toView:self]; x1 = fromFrame.origin.x+fromFrame.size.width/2; y1 = fromFrame.origin.y+fromFrame.size.height/2; x2 = toFrame.origin.x+toFrame.size.width/2; y2 = toFrame.origin.y+toFrame.size.height/2; PSmoveto(x1, y1); PSlineto(x2, y2); if ([superview getSelected]==self) { gray = NX_WHITE; width = LINEWIDTH; } else { if ( ([fromFakeUG isClavier] && [toFakeUG isPatchParameter]) || ([fromFakeUG isMidi] && [toFakeUG isPatchParameter])) { gray = 0.25; width = 2*LINEWIDTH; } else { if (xmemory) { gray = NX_DKGRAY; width = LINEWIDTH; } else { gray = NX_BLACK; width = LINEWIDTH; } } } PSsetgray(gray); PSsetlinewidth(width); PSstroke(); NXPing(); } } return self; } - write:(NXTypedStream *) stream { char *aName; aName = theName; [super write:stream]; if (inspector) { useInspectorRect = YES; [inspector getFrame:&inspectorRect]; } else { useInspectorRect = NO; inspectorRect.origin.x = -1; inspectorRect.origin.y = -1; inspectorRect.size.width = -1; inspectorRect.size.height = -1; } NXWriteTypes(stream, "*", &aName); NXWriteTypes(stream, "@", &fromNode); NXWriteTypes(stream, "@", &toNode); NXWriteTypes(stream, "c", &xmemory); NXWriteTypes(stream, "i", &allocOrder); NXWriteTypes(stream, "d", &inspectorRect.origin.x); NXWriteTypes(stream, "d", &inspectorRect.origin.y); NXWriteTypes(stream, "d", &inspectorRect.size.width); NXWriteTypes(stream, "d", &inspectorRect.size.height); NXWriteTypes(stream, "c", &useInspectorRect); NXWriteTypes(stream, "c", &inspectorDisplayed); return self; } - read:(NXTypedStream *) stream { int version; id aPP; char *old_name; isAllocated = NO; [super read:stream]; allocOrder = 1; useInspectorRect = NO; inspectorRectJustLoaded = NO; version = NXTypedStreamClassVersion(stream, "FakePatchPoint"); switch (version) { case(3): { NXReadTypes(stream, "*", &old_name); NXReadTypes(stream, "@", &fromNode); NXReadTypes(stream, "@", &toNode); NXReadTypes(stream, "c", &xmemory); NXReadTypes(stream, "i", &allocOrder); NXReadTypes(stream, "d", &inspectorRect.origin.x); NXReadTypes(stream, "d", &inspectorRect.origin.y); NXReadTypes(stream, "d", &inspectorRect.size.width); NXReadTypes(stream, "d", &inspectorRect.size.height); NXReadTypes(stream, "c", &useInspectorRect); NXReadTypes(stream, "c", &inspectorDisplayed); inspectorRectJustLoaded = YES; if (old_name) { strcpy(theName, old_name); } else { strcpy(theName, ""); } break; } case(2): { NXReadTypes(stream, "*@@ci", &old_name, &fromNode, &toNode, &xmemory, &allocOrder); if (old_name) { strcpy(theName, old_name); } else { strcpy(theName, ""); } break; } default: { /* Older versions */ /*ME* Observed malloc error on an initial attempt to load an old file */ NXReadTypes(stream, "*@@c@", &old_name, &fromNode, &toNode, &xmemory, &aPP); allocOrder = 1; if (old_name) { strcpy(theName, old_name); } else { strcpy(theName, ""); } } } return self; } - printSelf { int i; printf("\n===============================================\n"); printf("- (FakePatchPoint %s) %d toNodes\n", [self getName], (int) [toNode count]); printf(" > fromNode: goes to tag %d on fakeUG %s\n", [fromNode getTag], [[fromNode superview] getName]); for (i=0; i<[toNode count]; i++) { printf(" > toNode %d: goes to tag %d on fakeUG: %s\n", i, [[toNode objectAt:i] getTag], [[[toNode objectAt:i] superview] getName]); } return self; } - displayIfDoubleClick { clickCount++; if (clickCount >= 2) { clickCount = 0; [self displayInspector]; } return self; } - highlightSelf { if ( (![theSP windowMiniaturized]) && doHighlight) { [superview setSelected:self]; [window removeFromEventMask:NX_LMOUSEDRAGGEDMASK]; [window flushWindow]; [superview display]; } return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.