mirror of
https://github.com/nickshanks/ResKnife.git
synced 2024-12-22 02:29:56 +00:00
Improve Template Editor.
This commit is contained in:
parent
e5f925eff4
commit
3208fcd52b
@ -2,11 +2,32 @@
|
||||
|
||||
@interface Element : NSObject
|
||||
{
|
||||
NSString *type;
|
||||
NSString *label;
|
||||
NSString *type;
|
||||
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
|
||||
|
@ -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
|
||||
|
@ -5,13 +5,12 @@
|
||||
|
||||
@interface TemplateWindowController : NSWindowController <ResKnifePluginProtocol>
|
||||
{
|
||||
id <ResKnifeResourceProtocol> resource;
|
||||
NSMutableArray *tmpl;
|
||||
}
|
||||
IBOutlet NSMatrix *fieldsMatrix;
|
||||
|
||||
// conform to the ResKnifePluginProtocol with the inclusion of these methods
|
||||
- (id)initWithResource:(id)newResource;
|
||||
- (id)initWithResources:(id)newResource, ...;
|
||||
NSMutableArray *tmpl;
|
||||
NSMutableArray *res;
|
||||
id <ResKnifeResourceProtocol> resource;
|
||||
}
|
||||
|
||||
// normal methods
|
||||
- (void)readTemplate:(id <ResKnifeResourceProtocol>)tmpl;
|
||||
|
@ -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,6 +56,7 @@ NSString *ResourceDidChangeNotification = @"ResourceDidChangeNotification";
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
[(id)resource autorelease];
|
||||
[tmpl autorelease];
|
||||
[res autorelease];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@ -65,6 +64,10 @@ NSString *ResourceDidChangeNotification = @"ResourceDidChangeNotification";
|
||||
{
|
||||
[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];
|
||||
[self createUI];
|
||||
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user