This is DefaultController.m in view mode; [Download] [Up]
// Sat Oct 12 11:14:48 MET 1996 /* toDo: - do some guesses for type on new connection (via isKindOf:) */ #import "DefaultController.h" #define DEFCTL_VERSION 1 @interface Object(__WarningKiller) - target; -(SEL) action; @end // so that all gadgets can notify themselves to us on window-close or app-terminate @implementation Object(_ListActionPerform) - _sendAction { SEL action=0; id target=nil; if([self respondsTo:@selector(target)]) target=[self target]; if([self respondsTo:@selector(action)]) action=[self action]; if(target && action) [NXApp sendAction:action to:target from:self]; return self; } @end @implementation DefaultController:Object + initialize { if (self == [DefaultController class]) { /* * **** Archiving: READ ME **** After bumping the _VERSION, it is * considered common practice to add a comment line indicating the new * version number, date, and modifier. Optionally, the reason for the * change. There is no need to modify the setVersion message. */ // version 1: initial. (db) [[DefaultController class] setVersion:DEFCTL_VERSION]; } return self; } - init { names=[[Storage alloc] initCount:1 elementSize:sizeof(char*) description:"*"]; types=[[Storage alloc] initCount:1 elementSize:sizeof(int ) description:"i"]; gadgets =[[List alloc] init]; return self; } -(List*) gadgets { return gadgets; } -(unsigned)indexOf:anObject { return [gadgets indexOf:anObject]; } - removeObjectAt:(unsigned)index { id currObjc=[gadgets objectAt:index]; if(currObjc) { [names removeElementAt:index]; [types removeElementAt:index]; } return [gadgets removeObjectAt:index]; } - objectAt:(unsigned)index { return [gadgets objectAt:index]; } - addObjectIfAbsent:anObject { return [self registerName:"SomeDefName" andType:DCT_string for:anObject]; } -(unsigned) count { return [gadgets count]; } -(const char*) getDefaultOfName:(const char*) defaultName { const char *ptr; if(!defaultName || !strlen(defaultName)) return ""; ptr=NXGetDefaultValue([NXApp appName], defaultName); return ptr? ptr:""; } - loadValueFor:currObjc { const char *aName; DefaultControllerType_t aType; if([self getName:&aName andType:&aType for:currObjc]) { switch(aType) { case DCT_string: [currObjc setStringValue:[self getDefaultOfName:aName]]; break; case DCT_int: [currObjc setIntValue:atoi([self getDefaultOfName:aName])]; break; case DCT_float: case DCT_double: [currObjc setFloatValue:atof([self getDefaultOfName:aName])]; break; case DCT_bool: if(!strcmp([self getDefaultOfName:aName],"YES")) [currObjc setState:1]; else [currObjc setState:0]; break; case DCT_tag: [currObjc selectCellWithTag:atoi([self getDefaultOfName:aName])]; break; case DCT_color: { float r,g,b,a; sscanf([self getDefaultOfName:aName],"%f %f %f %f",&r,&g,&b,&a); [currObjc setColor:NXConvertRGBAToColor(r,g,b,a)]; } break; default: NXLogError("DefaultController: Undefined type: %d\n",aType); } } return self; } - doSetupConnections { int i; id currObjc; for(i=0; currObjc=[gadgets objectAt:i];i++) { if ([currObjc respondsTo:@selector(setTarget:)]) [currObjc setTarget:self]; if ([currObjc respondsTo:@selector(setAction:)]) [currObjc setAction:@selector(uiDataChanged:)]; [self loadValueFor:currObjc]; } return self; } - registerName:(const char*) aName andType:(DefaultControllerType_t) aType for:theGadget { char **ptr=malloc(sizeof(char*)); unsigned pos; if(!aName || !strlen(aName) || !theGadget) return nil; if((pos=[gadgets indexOf:theGadget]) == NX_NOT_IN_LIST) { [gadgets addObject:theGadget]; [names addElement:((*ptr)=NXCopyStringBuffer(aName),ptr)]; [types addElement:&aType]; } else { [names replaceElementAt:pos with:((*ptr)=NXCopyStringBuffer(aName),ptr)]; [types replaceElementAt:pos with:&aType]; } return self; } - getName:(const char**) aName andType:(DefaultControllerType_t*) aType for:theGadget { unsigned pos; if(!theGadget) return nil; if((pos=[gadgets indexOf:theGadget]) != NX_NOT_IN_LIST) { if(aName) *aName=*(char**)[names elementAt:pos]; // some crazy indirection if(aType) *aType=*(int *)[types elementAt:pos]; return self; } if([theGadget isKindOf:[Matrix class]]) return [self getName:aName andType:aType for:[theGadget selectedCell]]; return nil; } - (int)setDefault:(const char *)defName to:(const char *)defValue { return NXWriteDefault( [NXApp appName], defName, defValue ); } - (int)setDefault:(const char *)defName toBool:(BOOL)defValue { return [self setDefault:defName to:(defValue ? "YES" : "NO")]; } - (int)setDefault:(const char *)defName toInt:(int)defValue { char intBuffer[80]; sprintf(intBuffer, "%i", defValue); return [self setDefault:defName to:intBuffer]; } - (int)setDefault:(const char *)defName toDouble:(double)defValue { char buf[80]; sprintf(buf,"%f",defValue); return [self setDefault:defName to:buf]; } - uiDataChanged:sender { const char *aName,*ptr; DefaultControllerType_t aType; int i; if([self getName:&aName andType:&aType for:sender]) { switch(aType) { case DCT_string: [self setDefault:aName to:[sender stringValue]]; break; case DCT_int: [self setDefault:aName toInt:[sender intValue]]; break; case DCT_float: case DCT_double: [self setDefault:aName toDouble:[sender doubleValue]]; break; case DCT_bool: [self setDefault:aName toBool:[sender intValue]]; break; case DCT_tag: [self setDefault:aName toInt:[[sender selectedCell] tag]]; break; case DCT_color: { char buf[128]; float r,g,b,a; NXConvertColorToRGBA([sender color],&r,&g,&b,&a); sprintf(buf,"%f %f %f %f",r,g,b,a); [self setDefault:aName to:buf]; } break; default: NXLogError("DefaultController: Undefined type: %d\n",aType); } } else NXLogError("DefaultController: Unregistered(unconnected) sender: %s\n", [[sender class] name]); // now do some EOF-like magic¼ for(i=0;[gadgets objectAt:i] && aName && (ptr=*(char**)[names elementAt:i]) ;i++) { if(!strcmp(aName,ptr)) [self loadValueFor:[gadgets objectAt:i]]; } return self; } - windowWillClose:sender { [gadgets makeObjectsPerform:@selector(_sendAction)]; // before we close collect all data return self; } - appWillTerminate:sender { [gadgets makeObjectsPerform:@selector(_sendAction)]; // before we close collect all data return self; } - awakeFromNib { [self doSetupConnections]; return self; } #if 0 - copyFromZone:(NXZone*) theZone { id copy=[super copyFromZone:theZone]; // return copy; } #endif // archiving - read: (NXTypedStream*)stream { int version; [super read:stream]; switch (version = NXTypedStreamClassVersion(stream, "DefaultController")) { case 0: // unimplemented break; case DEFCTL_VERSION: gadgets= NXReadObject(stream); names=NXReadObject(stream); types=NXReadObject(stream); break; default: NXLogError("[%s %s] - unknown version of %s in typed stream", [[self class] name], sel_getName(_cmd), [[DefaultController class] name]); break; } return self; } - write: (NXTypedStream*)stream { [super write:stream]; NXWriteObject(stream,gadgets); NXWriteObject(stream,names); NXWriteObject(stream,types); return self; } - free { [gadgets free]; // do not free the objects! [names free]; [types free]; return [super free]; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.