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];
}
@endThese are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.