diff --git a/Cocoa/Plug-Ins/Template Editor/Element.h b/Cocoa/Plug-Ins/Template Editor/Element.h index 1130c7b..6476938 100644 --- a/Cocoa/Plug-Ins/Template Editor/Element.h +++ b/Cocoa/Plug-Ins/Template Editor/Element.h @@ -2,11 +2,32 @@ @interface Element : NSObject { - NSString *label; - NSString *type; + NSString *type; + NSString *label; + union // for resource data only, ignored for templates + { + NSString *string; + NSNumber *number; + NSData *data; + BOOL boolean; + } elementData; } - (id)initWithType:(NSString *)typeValue andLabel:(NSString *)labelValue; + (id)elementOfType:(NSString *)typeValue withLabel:(NSString *)labelValue; +- (NSString *)label; +- (NSString *)type; +- (unsigned long)typeAsLong; +- (NSString *)string; +- (void)setString:(NSString *)string; +- (NSNumber *)number; +- (void)setNumber:(NSNumber *)number; +- (long)numberAsLong; +- (void)setNumberWithLong:(long)number; +- (NSData *)data; +- (void)setData:(NSData *)data; +- (BOOL)boolean; +- (void)setBoolean:(BOOL)boolean; + @end diff --git a/Cocoa/Plug-Ins/Template Editor/Element.m b/Cocoa/Plug-Ins/Template Editor/Element.m index cd1651b..a94f1ef 100644 --- a/Cocoa/Plug-Ins/Template Editor/Element.m +++ b/Cocoa/Plug-Ins/Template Editor/Element.m @@ -6,8 +6,8 @@ { // sets values directly for speed reasons (less messaging overhead) self = [super init]; - label = [labelValue copy]; type = [typeValue copy]; + label = [labelValue copy]; return self; } @@ -17,4 +17,80 @@ return [element autorelease]; } +- (id)copy +{ + Element *element = [[Element alloc] initWithType:type andLabel:label]; + // copy other stuff here + return element; +} + +/* ACCESSORS */ + +- (NSString *)label +{ + return label; +} + +- (NSString *)type +{ + return type; +} + +- (unsigned long)typeAsLong +{ + return *(unsigned long *)[type cString]; +} + +/* DATA ACCESSORS */ + +- (NSString *)string +{ + return elementData.string; +} + +- (void)setString:(NSString *)string +{ + elementData.string = [string retain]; +} + +- (NSNumber *)number +{ + return elementData.number; +} + +- (void)setNumber:(NSNumber *)number +{ + elementData.number = [number retain]; +} + +- (long)numberAsLong +{ + return [elementData.number longValue]; +} + +- (void)setNumberWithLong:(long)number +{ + elementData.number = [[NSNumber numberWithLong:number] retain]; +} + +- (NSData *)data +{ + return elementData.data; +} + +- (void)setData:(NSData *)data +{ + elementData.data = [data retain]; +} + +- (BOOL)boolean +{ + return elementData.boolean; +} + +- (void)setBoolean:(BOOL)boolean +{ + elementData.boolean = boolean; +} + @end diff --git a/Cocoa/Plug-Ins/Template Editor/TemplateWindowController.h b/Cocoa/Plug-Ins/Template Editor/TemplateWindowController.h index 615b8bf..fc01e5b 100644 --- a/Cocoa/Plug-Ins/Template Editor/TemplateWindowController.h +++ b/Cocoa/Plug-Ins/Template Editor/TemplateWindowController.h @@ -5,14 +5,13 @@ @interface TemplateWindowController : NSWindowController { + IBOutlet NSMatrix *fieldsMatrix; + + NSMutableArray *tmpl; + NSMutableArray *res; id resource; - NSMutableArray *tmpl; } -// conform to the ResKnifePluginProtocol with the inclusion of these methods -- (id)initWithResource:(id)newResource; -- (id)initWithResources:(id)newResource, ...; - // normal methods - (void)readTemplate:(id )tmpl; - (void)parseData; diff --git a/Cocoa/Plug-Ins/Template Editor/TemplateWindowController.m b/Cocoa/Plug-Ins/Template Editor/TemplateWindowController.m index 6d1f4c6..4cd3e9e 100644 --- a/Cocoa/Plug-Ins/Template Editor/TemplateWindowController.m +++ b/Cocoa/Plug-Ins/Template Editor/TemplateWindowController.m @@ -20,36 +20,34 @@ NSString *ResourceDidChangeNotification = @"ResourceDidChangeNotification"; - (id)initWithResource:(id)newResource { - self = [self initWithWindowNibName:@"TemplateWindow"]; - if( !self ) return self; - - // one instance of your principal class will be created for every resource the user wants to edit (similar to Windows apps) - resource = [newResource retain]; - tmpl = [[NSMutableArray alloc] init]; - - // load the window from the nib file and set it's title - [self window]; // implicitly loads nib - if( ![[resource name] isEqualToString:@""] ) - [[self window] setTitle:[resource name]]; -// else leave name as set in nib file - return self; + return [self initWithResources:newResource, nil]; } - (id)initWithResources:(id)newResource, ... { + id currentResource; va_list resourceList; va_start( resourceList, newResource ); - self = [self initWithResource:newResource]; - if( self ) + + // one instance of your principal class will be created for every resource set the user wants to edit (similar to Windows apps) + self = [self initWithWindowNibName:@"TemplateWindow"]; + if( !self ) { - id currentResource; - [self readTemplate:va_arg( resourceList, id )]; // reads (but doesn't retain) the TMPL resource - while( currentResource = va_arg( resourceList, id ) ) - { - NSLog( @"too many params passed to -initWithResources: %@", [currentResource description] ); - } + va_end( resourceList ); + return self; } + + resource = [newResource retain]; + tmpl = [[NSMutableArray alloc] init]; + res = [[NSMutableArray alloc] init]; + + [self readTemplate:va_arg( resourceList, id )]; // reads (but doesn't retain) the TMPL resource + while( currentResource = va_arg( resourceList, id ) ) + NSLog( @"too many params passed to -initWithResources: %@", [currentResource description] ); va_end( resourceList ); + + // load the window from the nib + [self window]; return self; } @@ -58,12 +56,17 @@ NSString *ResourceDidChangeNotification = @"ResourceDidChangeNotification"; [[NSNotificationCenter defaultCenter] removeObserver:self]; [(id)resource autorelease]; [tmpl autorelease]; + [res autorelease]; [super dealloc]; } - (void)windowDidLoad { [super windowDidLoad]; + + // set the window's title + if( ![[resource name] isEqualToString:@""] ) + [[self window] setTitle:[resource name]]; // parse data using pre-scanned template and create the fields as needed [self parseData]; @@ -85,7 +88,7 @@ NSString *ResourceDidChangeNotification = @"ResourceDidChangeNotification"; else { NSString *label, *type; - char *currentByte = [[tmplResource data] bytes]; + char *currentByte = (char *) [[tmplResource data] bytes]; unsigned long size = [[tmplResource data] length], position = 0; while( position < size ) { @@ -99,6 +102,7 @@ NSString *ResourceDidChangeNotification = @"ResourceDidChangeNotification"; currentByte += 4; // add element to array +// NSLog( @"Adding object %@ of type %@ to array", label, type ); [tmpl addObject:[Element elementOfType:type withLabel:label]]; } } @@ -106,18 +110,96 @@ NSString *ResourceDidChangeNotification = @"ResourceDidChangeNotification"; - (void)parseData { - + unsigned long position = 0, loopStart; + char *data = (char *) [resource data]; + + // creates an array of elements containing the data in whatever format the template dictates + // array can then simply be manipulated one element at a time, or flattened to save + Element *currentTemplateElement, *resourceElement; + NSEnumerator *enumerator = [tmpl objectEnumerator]; + while( currentTemplateElement = [enumerator nextObject] ) + { + unsigned long type = [currentTemplateElement typeAsLong]; + resourceElement = [[currentTemplateElement copy] autorelease]; + switch( type ) + { + /* Alignment */ + case 'AWRD': + position += position % 2; + break; + case 'ALNG': + position += position % 4; + break; + + /* Fillers */ + case 'FBYT': + position += 1; + break; + case 'FWRD': + position += 2; + break; + case 'FLNG': + position += 4; + break; + + /* Decimal */ + case 'DBYT': + [resourceElement setNumberWithLong:*(char *)(data + position)]; + position += 1; + break; + case 'DWRD': + [resourceElement setNumberWithLong:*(int *)(data + position)]; + position += 2; + break; + case 'DLNG': + [resourceElement setNumberWithLong:*(long *)(data + position)]; + position += 4; + break; + + /* Hex */ + case 'HBYT': + [resourceElement setData:[NSData dataWithBytes:(void *)(data + position) length:1]]; + position += 1; + break; + case 'HWRD': + [resourceElement setData:[NSData dataWithBytes:(void *)(data + position) length:2]]; + position += 2; + break; + case 'HLNG': + [resourceElement setData:[NSData dataWithBytes:(void *)(data + position) length:4]]; + position += 4; + break; + + /* Cxxx, Hxxx or P0xx */ + default: + { unsigned long length = type & 0x00FFFFFF; + NSLog( @"error, Cxxx, Hxxx and P0xx unsupported" ); + resourceElement = nil; // relies on element being previously autoreleased to avoid a leak + } break; + } // end switch + if( resourceElement ) [res addObject:resourceElement]; + } // end while loop } - (void)createUI { - NSScrollView *scrollView = [[NSScrollView alloc] initWithFrame:[NSWindow contentRectForFrameRect:[[[self window] contentView] frame] styleMask:0]]; - [[[self window] contentView] addSubview:scrollView]; + // iterate through res creating fields + Element *currentResourceElement; + NSEnumerator *enumerator = [res objectEnumerator]; + NSLog( @"%d", [res count] ); + while( currentResourceElement = [enumerator nextObject] ) + { + NSFormCell *newField = [[NSFormCell alloc] initTextCell:[currentResourceElement label]]; + [fieldsMatrix addRowWithCells:[NSArray arrayWithObject:[newField autorelease]]]; + NSLog( @"%@ added to matrix", [newField description] ); + } + NSLog( [fieldsMatrix description] ); + [fieldsMatrix setNeedsDisplay]; } - (void)resourceDataDidChange:(NSNotification *)notification { - // ensure it's our resource which got changed (should always be true, we don't register for other resource notifications) + // ensure it's our resource which got changed (should always be true, we don't register for notifications on other resource objects) if( [notification object] == (id)resource ) [self refreshData:[resource data]]; } @@ -125,6 +207,7 @@ NSString *ResourceDidChangeNotification = @"ResourceDidChangeNotification"; - (void)refreshData:(NSData *)data; { #warning Should update data when datachanged notification received + // put data from resource into correct fields } - (id)resource