diff --git a/Carbon/ResKnife.h b/Carbon/ResKnife.h index 03fc7c8..f651f7e 100644 --- a/Carbon/ResKnife.h +++ b/Carbon/ResKnife.h @@ -29,7 +29,7 @@ With thanks to: For: // compile options #if TARGET_API_MAC_CARBON - #define USE_NIBS 1 // toggle this + #define USE_NIBS 0 // toggle this #else #define USE_NIBS 0 // leave this set to zero #endif diff --git a/Carbon/Resources/Carbon.r b/Carbon/Resources/Carbon.r index 93181e8..66b5fb8 100644 --- a/Carbon/Resources/Carbon.r +++ b/Carbon/Resources/Carbon.r @@ -1,7 +1,7 @@ -#if defined(__MWERKS__) // compiling with CodeWarrior - #include "MacTypes.r" -#else +#if defined(__APPLE_CC__) // compiling with gcc #include +#else // compiling with CodeWarrior, __MWERKS__ + #include #endif /*** CARBON RESOURCES ***/ diff --git a/Carbon/Resources/ResKnife.r b/Carbon/Resources/ResKnife.r index 5e0c2b4..624071d 100644 --- a/Carbon/Resources/ResKnife.r +++ b/Carbon/Resources/ResKnife.r @@ -1,7 +1,7 @@ -#if defined(__MWERKS__) // compiling with CodeWarrior - #include "MacTypes.r" -#else +#if defined(__APPLE_CC__) // compiling with gcc #include +#else // compiling with CodeWarrior, __MWERKS__ + #include #endif /*** APPLE MENU ***/ diff --git a/Cocoa/Categories/NSOutlineView-SelectedItems.h b/Cocoa/Categories/NSOutlineView-SelectedItems.h index 68e8dc7..ed75c37 100644 --- a/Cocoa/Categories/NSOutlineView-SelectedItems.h +++ b/Cocoa/Categories/NSOutlineView-SelectedItems.h @@ -1,6 +1,6 @@ #import -@interface NSOutlineView (SelectedItems) +@interface NSOutlineView (ResKnifeSelectedItemExtensions) - (id)selectedItem; - (NSArray *)selectedItems; diff --git a/Cocoa/Categories/NSOutlineView-SelectedItems.m b/Cocoa/Categories/NSOutlineView-SelectedItems.m index c11735a..00c3b84 100644 --- a/Cocoa/Categories/NSOutlineView-SelectedItems.m +++ b/Cocoa/Categories/NSOutlineView-SelectedItems.m @@ -1,8 +1,8 @@ #import "NSOutlineView-SelectedItems.h" -/* The methods in the following catagory were taken from OmniAppKit */ +/* The methods in the following catagory were based upon those in OmniAppKit */ -@implementation NSOutlineView (SelectedItems) +@implementation NSOutlineView (ResKnifeSelectedItemExtensions) - (id)selectedItem { diff --git a/Cocoa/Classes/OutlineViewDelegate.h b/Cocoa/Classes/OutlineViewDelegate.h index 9611e39..a03db5b 100644 --- a/Cocoa/Classes/OutlineViewDelegate.h +++ b/Cocoa/Classes/OutlineViewDelegate.h @@ -3,6 +3,8 @@ #import "SizeFormatter.h" #import "AttributesFormatter.h" +@class Resource; + @interface OutlineViewDelegate : NSObject { IBOutlet NSWindow *window; @@ -10,4 +12,8 @@ IBOutlet SizeFormatter *sizeFormatter; IBOutlet AttributesFormatter *attributesFormatter; } + +int compareResourcesAscending( Resource *r1, Resource *r2, void *context ); +int compareResourcesDescending( Resource *r1, Resource *r2, void *context ); + @end diff --git a/Cocoa/Classes/OutlineViewDelegate.m b/Cocoa/Classes/OutlineViewDelegate.m index c072658..384a84c 100644 --- a/Cocoa/Classes/OutlineViewDelegate.m +++ b/Cocoa/Classes/OutlineViewDelegate.m @@ -1,13 +1,49 @@ #import "OutlineViewDelegate.h" -#import "ResourceNameCell.h" #import "Resource.h" +#import "ResourceDataSource.h" +#import "ResourceNameCell.h" #import "ApplicationDelegate.h" @implementation OutlineViewDelegate - (void)tableView:(NSTableView*)tableView didClickTableColumn:(NSTableColumn *)tableColumn { + NSArray *oldResources = [(ResourceDataSource *)[tableView dataSource] resources]; + NSArray *newResources; + + NSLog( @"Clicked table column: %@", tableColumn ); + + // sort the array + if( ![[tableView indicatorImageInTableColumn:tableColumn] isFlipped] ) + newResources = [oldResources sortedArrayUsingFunction:compareResourcesAscending context:(void*)[tableColumn identifier]]; + else + newResources = [oldResources sortedArrayUsingFunction:compareResourcesDescending context:(void*)[tableColumn identifier]]; + + // swap new array for old one + [(ResourceDataSource *)[tableView dataSource] setResources:[NSMutableArray arrayWithArray:newResources]]; + [tableView reloadData]; +} +int compareResourcesAscending( Resource *r1, Resource *r2, void *context ) +{ + NSString *key = (NSString *)context; + SEL sel = NSSelectorFromString(key); + + if( [key isEqualToString:@"name"] || [key isEqualToString:@"type"] ) + return [(NSString *)[r1 performSelector:sel] caseInsensitiveCompare: (NSString *)[r2 performSelector:sel]]; + else + return [(NSNumber *)[r1 performSelector:sel] compare: (NSNumber *)[r2 performSelector:sel]]; +} + +int compareResourcesDescending( Resource *r1, Resource *r2, void *context ) +{ + NSString *key = (NSString *)context; + SEL sel = NSSelectorFromString(key); + + if( [key isEqualToString:@"name"] || [key isEqualToString:@"type"] ) + return -1 * [(NSString *)[r1 performSelector:sel] caseInsensitiveCompare: (NSString *)[r2 performSelector:sel]]; + else + return -1 * [(NSNumber *)[r1 performSelector:sel] compare: (NSNumber *)[r2 performSelector:sel]]; } - (BOOL)outlineView:(NSOutlineView *)outlineView shouldEditTableColumn:(NSTableColumn *)tableColumn item:(id)item diff --git a/Cocoa/Classes/Resource.m b/Cocoa/Classes/Resource.m index 00b4f6e..5f76d22 100644 --- a/Cocoa/Classes/Resource.m +++ b/Cocoa/Classes/Resource.m @@ -130,6 +130,11 @@ /* Accessors */ +- (void)touch +{ + [self setDirty:YES]; +} + - (BOOL)isDirty { return dirty; @@ -247,4 +252,11 @@ } } +/* description */ + +- (NSString *)description +{ + return [NSString stringWithFormat:@"\nName: %@\nType: %@ ID: %@\nModified: %@", name, type, resID, dirty? @"YES":@"NO"]; +} + @end diff --git a/Cocoa/Classes/ResourceDataSource.m b/Cocoa/Classes/ResourceDataSource.m index 06aaa98..e473472 100644 --- a/Cocoa/Classes/ResourceDataSource.m +++ b/Cocoa/Classes/ResourceDataSource.m @@ -113,7 +113,7 @@ NSString *DataSourceDidRemoveResourceNotification = @"DataSourceDidRemoveResourc NSEnumerator *enumerator = [resources objectEnumerator]; while( resource = [enumerator nextObject] ) { - if( [[resource resID] isEqualToNumber:resID] && [[resource type] isEqualToString:type] ) + if( resID && [[resource resID] isEqualToNumber:resID] && type && [[resource type] isEqualToString:type] ) return resource; } return nil; diff --git a/Cocoa/Classes/ResourceDocument.m b/Cocoa/Classes/ResourceDocument.m index 9b4d79d..dd05b6b 100644 --- a/Cocoa/Classes/ResourceDocument.m +++ b/Cocoa/Classes/ResourceDocument.m @@ -328,11 +328,14 @@ static NSString *RKShowInfoItemIdentifier = @"com.nickshanks.resknife.toolbar.sh - (IBAction)playSound:(id)sender { - // bug: Can only cope with one selected item - Resource *resource = [outlineView itemAtRow:[outlineView selectedRow]]; - NSSound *sound = [[NSSound alloc] initWithData:[resource data]]; - [sound setDelegate:self]; - [sound play]; + // bug: can only cope with one selected item + NSData *data = [(Resource *)[outlineView itemAtRow:[outlineView selectedRow]] data]; + if( data && [data length] != 0 ) + { + SndListPtr sndPtr = (SndListPtr) [data bytes]; + SndPlay( nil, &sndPtr, false ); + } + else NSBeep(); } - (void)sound:(NSSound *)sound didFinishPlaying:(BOOL)finished diff --git a/Cocoa/Classes/SizeFormatter.h b/Cocoa/Classes/SizeFormatter.h index d0efe87..972808e 100644 --- a/Cocoa/Classes/SizeFormatter.h +++ b/Cocoa/Classes/SizeFormatter.h @@ -1,8 +1,6 @@ #import @interface SizeFormatter : NSNumberFormatter -{ -} - (NSString *)stringForObjectValue:(id)obj; diff --git a/Cocoa/Plug-Ins/ResKnifeResourceProtocol.h b/Cocoa/Plug-Ins/ResKnifeResourceProtocol.h index 89da6e5..0ac7fe6 100644 --- a/Cocoa/Plug-Ins/ResKnifeResourceProtocol.h +++ b/Cocoa/Plug-Ins/ResKnifeResourceProtocol.h @@ -4,6 +4,7 @@ @protocol ResKnifeResourceProtocol +- (void)touch; - (BOOL)isDirty; - (NSString *)name; - (void)setName:(NSString *)newName; diff --git a/Cocoa/Plug-Ins/Template Editor/Element.h b/Cocoa/Plug-Ins/Template Editor/Element.h index 6476938..5c1284c 100644 --- a/Cocoa/Plug-Ins/Template Editor/Element.h +++ b/Cocoa/Plug-Ins/Template Editor/Element.h @@ -2,9 +2,10 @@ @interface Element : NSObject { - NSString *type; - NSString *label; - union // for resource data only, ignored for templates + NSString *type; + NSString *label; + NSMutableArray *subelements; // elements of a list type have a sub-array of elements + union // for resource data only, ignored for templates { NSString *string; NSNumber *number; @@ -18,6 +19,7 @@ - (NSString *)label; - (NSString *)type; +- (NSMutableArray *)subelements; - (unsigned long)typeAsLong; - (NSString *)string; - (void)setString:(NSString *)string; diff --git a/Cocoa/Plug-Ins/Template Editor/Element.m b/Cocoa/Plug-Ins/Template Editor/Element.m index a94f1ef..3c1ccb4 100644 --- a/Cocoa/Plug-Ins/Template Editor/Element.m +++ b/Cocoa/Plug-Ins/Template Editor/Element.m @@ -41,6 +41,18 @@ return *(unsigned long *)[type cString]; } +- (NSMutableArray *)subelements; +{ + long myType = [self typeAsLong]; + if( myType == 'LSTB' || myType == 'LSTC' ) + { + if( subelements == nil ) + subelements = [[NSMutableArray alloc] init]; + } + else subelements = nil; + return subelements; +} + /* DATA ACCESSORS */ - (NSString *)string diff --git a/Cocoa/Plug-Ins/Template Editor/English.lproj/TemplateWindow.nib/classes.nib b/Cocoa/Plug-Ins/Template Editor/English.lproj/TemplateWindow.nib/classes.nib new file mode 100644 index 0000000..f12514d --- /dev/null +++ b/Cocoa/Plug-Ins/Template Editor/English.lproj/TemplateWindow.nib/classes.nib @@ -0,0 +1,12 @@ +{ + IBClasses = ( + {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, + { + CLASS = TemplateWindowController; + LANGUAGE = ObjC; + OUTLETS = {fieldsMatrix = NSMatrix; }; + SUPERCLASS = NSWindowController; + } + ); + IBVersion = 1; +} \ No newline at end of file diff --git a/Cocoa/Plug-Ins/Template Editor/English.lproj/TemplateWindow.nib/info.nib b/Cocoa/Plug-Ins/Template Editor/English.lproj/TemplateWindow.nib/info.nib new file mode 100644 index 0000000..afa3a5b --- /dev/null +++ b/Cocoa/Plug-Ins/Template Editor/English.lproj/TemplateWindow.nib/info.nib @@ -0,0 +1,12 @@ + + + + + IBDocumentLocation + 672 193 356 240 0 0 1600 1002 + IBFramework Version + 286.0 + IBSystem Version + 6D52 + + diff --git a/Cocoa/Plug-Ins/Template Editor/English.lproj/TemplateWindow.nib/objects.nib b/Cocoa/Plug-Ins/Template Editor/English.lproj/TemplateWindow.nib/objects.nib new file mode 100644 index 0000000..8704de2 Binary files /dev/null and b/Cocoa/Plug-Ins/Template Editor/English.lproj/TemplateWindow.nib/objects.nib differ diff --git a/Cocoa/Plug-Ins/Template Editor/TemplateWindowController.m b/Cocoa/Plug-Ins/Template Editor/TemplateWindowController.m index 30ce94b..a39b017 100644 --- a/Cocoa/Plug-Ins/Template Editor/TemplateWindowController.m +++ b/Cocoa/Plug-Ins/Template Editor/TemplateWindowController.m @@ -96,9 +96,13 @@ - (void)parseData { - unsigned long position = 0, loopStart; + unsigned long position = 0; char *data = (char *) [resource data]; + // used for nesting of elements, 'target' is current object to append to, targetStack is a FILO stack of mutable array pointers + NSMutableArray *target = res; + NSMutableArray *targetArray = [NSMutableArray arrayWithObject:res]; + // 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; @@ -134,7 +138,7 @@ position += 1; break; case 'DWRD': - [resourceElement setNumberWithLong:*(int *)(data + position)]; + [resourceElement setNumberWithLong:*(short *)(data + position)]; position += 2; break; case 'DLNG': @@ -155,34 +159,89 @@ [resourceElement setData:[NSData dataWithBytes:(void *)(data + position) length:4]]; position += 4; break; + case 'HEXD': + // bug: doesn't check HEXD is the last element + [resourceElement setData:[NSData dataWithBytes:(void *)(data + position) length:([[resource size] intValue] - position)]]; + position = [[resource size] intValue]; + + /* List Counts */ + case 'BCNT': + case 'BZCT': + // bug: how big are these various count fields? + [resourceElement setNumberWithLong:*(char *)(data + position)]; + position += 1; + break; + case 'OCNT': + case 'ZCNT': + // bug: how big are these various count fields? + [resourceElement setNumberWithLong:*(short *)(data + position)]; + position += 2; + break; + case 'LCNT': + case 'LZCT': + // bug: how big are these various count fields? + [resourceElement setNumberWithLong:*(long *)(data + position)]; + position += 4; + break; + + /* List beginning and end */ + case 'LSTB': + case 'LSTC': + target = [resourceElement subelements]; + [targetArray addObject:target]; + break; + case 'LSTE': + // bug: if there is a LSTE without a preceeding LSTB or LSTC this will crash + [targetArray removeLastObject]; + target = [targetArray lastObject]; + resourceElement = nil; // relies on element being previously autoreleased to avoid a leak + break; /* Cxxx, Hxxx or P0xx */ default: - { unsigned long length = type & 0x00FFFFFF; - NSLog( @"error, Cxxx, Hxxx and P0xx unsupported" ); + // bug: should look for Cxxx, Hxxx or P0xx and complain if it's something else (an unknown type)!! + {/* long lengthStr = (type & 0x00FFFFFF) << 8; + unsigned long length = strtoul( (char *) &lengthStr, nil, 10 ); + */ char *lengthStr = (type & 0x00FFFFFF) & (3 << 24); + unsigned long length; + StringToNum(lengthStr, &length); + NSLog( @"error, Cxxx, Hxxx and P0xx unsupported, skipping %d bytes", length ); resourceElement = nil; // relies on element being previously autoreleased to avoid a leak + position += length; } break; } // end switch - if( resourceElement ) [res addObject:resourceElement]; + if( resourceElement ) [target addObject:resourceElement]; } // end while loop } - (void)createUI { // 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] ); - } + [self enumerateElements:res]; NSLog( [fieldsMatrix description] ); [fieldsMatrix setNeedsDisplay]; } +- (void)enumerateElements:(NSMutableArray *)elements +{ + // iterate through the array of resource elements, creating fields + Element *currentResourceElement; + NSEnumerator *enumerator = [elements objectEnumerator]; + NSLog( @"%d", [elements count] ); + while( currentResourceElement = [enumerator nextObject] ) + { + // if element is a container, iterate inside it first + if( [currentResourceElement subelements] ) + [self enumerateElements:[currentResourceElement subelements]]; + else // element is normal + { + NSFormCell *newField = [[NSFormCell alloc] initTextCell:[currentResourceElement label]]; + [fieldsMatrix addRowWithCells:[NSArray arrayWithObject:[newField autorelease]]]; + NSLog( @"%@ added to matrix", [newField description] ); + } + } +} + - (void)resourceDataDidChange:(NSNotification *)notification { // ensure it's our resource which got changed (should always be true, we don't register for notifications on other resource objects) @@ -192,7 +251,6 @@ - (void)refreshData:(NSData *)data; { -#warning Should update data when datachanged notification received // put data from resource into correct fields } diff --git a/Hex Editor/Classes/Events.cpp b/Hex Editor/Classes/Events.cpp index 33f5dca..1cc5bc7 100644 --- a/Hex Editor/Classes/Events.cpp +++ b/Hex Editor/Classes/Events.cpp @@ -1,6 +1,6 @@ #include "Events.h" #include "HexWindow.h" -#include "Utility.h" +#include "HexUtility.h" extern globals g; extern prefs p; @@ -86,7 +86,7 @@ pascal OSStatus CarbonWindowEventHandler( EventHandlerCallRef handler, EventRef Boolean clickAscii = false; // clicked in ascii rect? - neither means not editing Plug_WindowRef plugWindow = Host_GetPlugWindowFromWindowRef( window ); HexWindowPtr hexWindow = (HexWindowPtr) Host_GetWindowRefCon( plugWindow ); - if( PtInRect( mouse, &hexWindow->hexRect ) ) { clickHex = true; hexWindow->editingHex = true; } + if( PtInRect( mouse, &hexWindow->hexRect ) ) { clickHex = true; hexWindow->editingHex = true; } if( PtInRect( mouse, &hexWindow->asciiRect ) ) { clickAscii = true; hexWindow->editingHex = false; } if( clickHex || clickAscii ) error = HandleEditClick( window, event, mouse, (EventModifiers) LoWord(modifiers) ); else error = eventNotHandledErr; diff --git a/Hex Editor/Classes/HexWindow.cpp b/Hex Editor/Classes/HexWindow.cpp index 8788e2b..5901f5c 100644 --- a/Hex Editor/Classes/HexWindow.cpp +++ b/Hex Editor/Classes/HexWindow.cpp @@ -1,7 +1,7 @@ #include "HexWindow.h" #include "Events.h" -#include "stdio.h" -// #include "strings.h" +#include +#include extern globals g; extern prefs p; @@ -303,8 +303,9 @@ OSStatus HexWindow::DrawContent( EventRef event ) if( currentByte < length ) { // BlockMoveData( *data + currentByte, &ascii, 1 ); - hex1 = *(*data + currentByte); - hex2 = *(*data + currentByte); + // hex1 = *(*data + currentByte); + // hex2 = *(*data + currentByte); + ascii = hex1 = hex2 = *(*data + currentByte); hex1 >>= 4; hex1 &= 0x0F; hex2 &= 0x0F; diff --git a/Hex Editor/Classes/Initalisation.cpp b/Hex Editor/Classes/Initalisation.cpp index 6e59f3b..9e73100 100644 --- a/Hex Editor/Classes/Initalisation.cpp +++ b/Hex Editor/Classes/Initalisation.cpp @@ -1 +1 @@ -#include "Initalisation.h" #include "HexWindow.h" #include "Events.h" #include "Utility.h" globals g; prefs p; /************************/ /* EDITOR INITALIZATION */ /************************/ /*** INITALISE GLOBALS ***/ OSStatus InitGlobals( void ) { // get system version OSStatus error = Gestalt( gestaltSystemVersion, &g.systemVersion ); if( error ) return error; // set up colours SetColour( &g.white, 0xFFFF, 0xFFFF, 0xFFFF ); SetColour( &g.bgColour, 0xEEEE, 0xEEEE, 0xEEEE ); SetColour( &g.sortColour, 0xDDDD, 0xDDDD, 0xDDDD ); SetColour( &g.bevelColour, 0xAAAA, 0xAAAA, 0xAAAA ); SetColour( &g.textColour, 0x7777, 0x7777, 0x7777 ); SetColour( &g.frameColour, 0x5555, 0x5555, 0x5555 ); SetColour( &g.black, 0x0000, 0x0000, 0x0000 ); // check appearance availablilty #if TARGET_API_MAC_CARBON g.useAppearance = true; #else ProcessSerialNumber psn; error = GetCurrentProcess( &psn ); if( error ) g.useAppearance = false; else g.useAppearance = IsAppearanceClient( &psn ); #endif // initalise preferences p.version = kHexEditorCurrentVersion; p.lowChar = 0x20; p.highChar = 0x7F; p.GWorldDepth = 8; return error; } /*** INITALISE NEW EDITOR INSTANCE ***/ OSStatus Plug_InitInstance( Plug_PlugInRef plug, Plug_ResourceRef resource ) { WindowRef window; OSStatus error = InitGlobals(); if( error ) return error; #if USE_NIBS // create a nib reference (only searches the application bundle) IBNibRef nibRef = null; error = CreateNibReference( CFSTR("Hex Editor"), &nibRef ); if( error != noErr || nibRef == null ) { // Host_DisplayError( "\pThe nib file reference could not be obtained.", "\p", 0 ); return error; } // create window error = CreateWindowFromNib( nibRef, CFSTR("Hex Window"), &window ); if( error != noErr || window == null ) { // Host_DisplayError( "\pA file window could not be obtained from the nib file.", "\p", 0 ); return error; } // dispose of nib ref DisposeNibReference( nibRef ); #elif TARGET_API_MAC_CARBON // create window Rect creationBounds; SetRect( &creationBounds, 0, 0, kDefaultWindowWidth, kDefaultWindowHeight ); OffsetRect( &creationBounds, 8, 48 ); WindowAttributes attributes = kWindowStandardDocumentAttributes | kWindowStandardHandlerAttribute | kWindowInWindowMenuAttribute; if( g.systemVersion >= kMacOSX ) attributes |= kWindowLiveResizeAttribute; error = CreateNewWindow( kDocumentWindowClass, attributes, &creationBounds, &window ); #else /* if( g.useAppearance && g.systemVersion >= kMacOSEight ) { window = GetNewCWindow( kFileWindow8, null, kFirstWindowOfClass ); themeSavvy = true; } else { */ window = GetNewCWindow( kFileWindow7, null, kFirstWindowOfClass ); DrawGrowIcon( window ); /* themeSavvy = false; } */ SizeWindow( window, kDefaultWindowWidth, kDefaultWindowHeight, false ); #endif // register mac window with host and retreive plug window Plug_WindowRef plugWindow = Host_RegisterWindow( plug, resource, window ); // cerate new hex window class HexWindowPtr hexWindow = new HexWindow( window ); // set window refCon to my class Host_SetWindowRefCon( plugWindow, (UInt32) hexWindow ); // load resource data into handle hexWindow->data = Host_GetResourceData( resource ); // handle disposed of by calling Host_ReleaseResData() // window is not yet active, will receive activate event soon hexWindow->activeWindow = false; // set window's background to default for theme if( g.useAppearance ) SetThemeWindowBackground( window, kThemeBrushModelessDialogBackgroundActive, false ); #if TARGET_API_MAC_CARBON // install window event handler EventHandlerRef ref = null; EventHandlerUPP handler = NewEventHandlerUPP( CarbonWindowEventHandler ); EventTypeSpec events[] = { { kEventClassWindow, kEventWindowClose }, { kEventClassWindow, kEventWindowActivated }, { kEventClassWindow, kEventWindowDeactivated }, { kEventClassWindow, kEventWindowBoundsChanging }, { kEventClassWindow, kEventWindowBoundsChanged }, { kEventClassWindow, kEventWindowHandleContentClick }, { kEventClassWindow, kEventWindowDrawContent }, { kEventClassKeyboard, kEventRawKeyDown }, { kEventClassKeyboard, kEventRawKeyRepeat } }; InstallWindowEventHandler( window, handler, GetEventTypeCount(events), events, plug, &ref ); // install HI event handler ref = null; handler = NewEventHandlerUPP( CarbonHIEventHandler ); EventTypeSpec HIevents[] = { { kEventClassMenu, kEventMenuEnableItems }, { kEventClassCommand, kEventCommandProcess } }; InstallWindowEventHandler( window, handler, GetEventTypeCount(HIevents), HIevents, null, &ref ); #else ClassicEventHandlerUPP handler = NewClassicEventHandlerUPP( ClassicWindowEventHandler ); Host_InstallClassicWindowEventHandler( plugWindow, handler ); #endif // get window rect Rect windowBounds; GetWindowPortBounds( window, &windowBounds ); #if USE_NIBS // get text edit controls which were created from the nib #elif TARGET_API_MAC_CARBON // create header ControlID id; Rect bounds = windowBounds; InsetRect( &bounds, -1, -1 ); bounds.bottom = bounds.top + kHeaderHeight +1; CreateWindowHeaderControl( window, &bounds, false, &hexWindow->header ); id.id = 0; id.signature = kHeaderSignature; SetControlID( hexWindow->header, &id ); // set up header font information ControlFontStyleRec fontStyle = {}; fontStyle.flags = kControlUseFontMask + kControlUseJustMask; fontStyle.font = kControlFontSmallSystemFont; fontStyle.just = teJustLeft; // create header static text controls GetWindowPortBounds( window, &windowBounds ); SetRect( &bounds, windowBounds.left +4, 2, (windowBounds.right - windowBounds.left) /2, kHeaderHeight -2 ); CreateStaticTextControl( window, &bounds, CFSTR("left side"), &fontStyle, &hexWindow->left ); id.id = 0; id.signature = kLeftTextSignature; SetControlID( hexWindow->left, &id ); fontStyle.just = teJustRight; SetRect( &bounds, (windowBounds.right - windowBounds.left) /2, 2, windowBounds.right -4, kHeaderHeight -2 ); CreateStaticTextControl( window, &bounds, CFSTR("right side"), &fontStyle, &hexWindow->right ); id.id = 0; id.signature = kRightTextSignature; SetControlID( hexWindow->right, &id ); // SetHeaderText(); // embed text controls within header EmbedControl( hexWindow->left, hexWindow->header ); EmbedControl( hexWindow->right, hexWindow->header ); #else // only create a scroll bar, draw everything else DrawWindow( window ); #endif #if TARGET_API_MAC_CARBON // install blinking timer EventLoopTimerUPP timerProc = NewEventLoopTimerUPP( BlinkInsertionPoint ); InstallEventLoopTimer( GetMainEventLoop(), 0, kEventDurationSecond /3, timerProc, window, &hexWindow->timer ); #endif // set scrollbar globals hexWindow->UpdateHexInfo(); // add menu to menu bar Host_AppendMenuToBar( plug, kEditorMenu ); // show window ShowWindow( window ); // this is the plug's responsibility SelectWindow( window ); BringToFront( window ); return error; } \ No newline at end of file +#include "Initalisation.h" #include "HexWindow.h" #include "Events.h" #include "HexUtility.h" globals g; prefs p; /************************/ /* EDITOR INITALIZATION */ /************************/ /*** INITALISE GLOBALS ***/ OSStatus InitGlobals( void ) { // get system version OSStatus error = Gestalt( gestaltSystemVersion, &g.systemVersion ); if( error ) return error; // set up colours SetColour( &g.white, 0xFFFF, 0xFFFF, 0xFFFF ); SetColour( &g.bgColour, 0xEEEE, 0xEEEE, 0xEEEE ); SetColour( &g.sortColour, 0xDDDD, 0xDDDD, 0xDDDD ); SetColour( &g.bevelColour, 0xAAAA, 0xAAAA, 0xAAAA ); SetColour( &g.textColour, 0x7777, 0x7777, 0x7777 ); SetColour( &g.frameColour, 0x5555, 0x5555, 0x5555 ); SetColour( &g.black, 0x0000, 0x0000, 0x0000 ); // check appearance availablilty #if TARGET_API_MAC_CARBON g.useAppearance = true; #else ProcessSerialNumber psn; error = GetCurrentProcess( &psn ); if( error ) g.useAppearance = false; else g.useAppearance = IsAppearanceClient( &psn ); #endif // initalise preferences p.version = kHexEditorCurrentVersion; p.lowChar = 0x20; p.highChar = 0x7F; p.GWorldDepth = 8; return error; } /*** INITALISE NEW EDITOR INSTANCE ***/ OSStatus Plug_InitInstance( Plug_PlugInRef plug, Plug_ResourceRef resource ) { WindowRef window; OSStatus error = InitGlobals(); if( error ) return error; #if USE_NIBS // create a nib reference (only searches the application bundle) IBNibRef nibRef = null; error = CreateNibReference( CFSTR("Hex Editor"), &nibRef ); if( error != noErr || nibRef == null ) { // Host_DisplayError( "\pThe nib file reference could not be obtained.", "\p", 0 ); return error; } // create window error = CreateWindowFromNib( nibRef, CFSTR("Hex Window"), &window ); if( error != noErr || window == null ) { // Host_DisplayError( "\pA file window could not be obtained from the nib file.", "\p", 0 ); return error; } // dispose of nib ref DisposeNibReference( nibRef ); #elif TARGET_API_MAC_CARBON // create window Rect creationBounds; SetRect( &creationBounds, 0, 0, kDefaultWindowWidth, kDefaultWindowHeight ); OffsetRect( &creationBounds, 8, 48 ); WindowAttributes attributes = kWindowStandardDocumentAttributes | kWindowStandardHandlerAttribute | kWindowInWindowMenuAttribute; if( g.systemVersion >= kMacOSX ) attributes |= kWindowLiveResizeAttribute; error = CreateNewWindow( kDocumentWindowClass, attributes, &creationBounds, &window ); #else /* if( g.useAppearance && g.systemVersion >= kMacOSEight ) { window = GetNewCWindow( kFileWindow8, null, kFirstWindowOfClass ); themeSavvy = true; } else { */ window = GetNewCWindow( kFileWindow7, null, kFirstWindowOfClass ); DrawGrowIcon( window ); /* themeSavvy = false; } */ SizeWindow( window, kDefaultWindowWidth, kDefaultWindowHeight, false ); #endif // register mac window with host and retreive plug window Plug_WindowRef plugWindow = Host_RegisterWindow( plug, resource, window ); // cerate new hex window class HexWindowPtr hexWindow = new HexWindow( window ); // set window refCon to my class Host_SetWindowRefCon( plugWindow, (UInt32) hexWindow ); // load resource data into handle hexWindow->data = Host_GetResourceData( resource ); // handle disposed of by calling Host_ReleaseResData() // window is not yet active, will receive activate event soon hexWindow->activeWindow = false; // set window's background to default for theme if( g.useAppearance ) SetThemeWindowBackground( window, kThemeBrushModelessDialogBackgroundActive, false ); #if TARGET_API_MAC_CARBON // install window event handler EventHandlerRef ref = null; EventHandlerUPP handler = NewEventHandlerUPP( CarbonWindowEventHandler ); EventTypeSpec events[] = { { kEventClassWindow, kEventWindowClose }, { kEventClassWindow, kEventWindowActivated }, { kEventClassWindow, kEventWindowDeactivated }, { kEventClassWindow, kEventWindowBoundsChanging }, { kEventClassWindow, kEventWindowBoundsChanged }, { kEventClassWindow, kEventWindowHandleContentClick }, { kEventClassWindow, kEventWindowDrawContent }, { kEventClassKeyboard, kEventRawKeyDown }, { kEventClassKeyboard, kEventRawKeyRepeat } }; InstallWindowEventHandler( window, handler, GetEventTypeCount(events), events, plug, &ref ); // install HI event handler ref = null; handler = NewEventHandlerUPP( CarbonHIEventHandler ); EventTypeSpec HIevents[] = { { kEventClassMenu, kEventMenuEnableItems }, { kEventClassCommand, kEventCommandProcess } }; InstallWindowEventHandler( window, handler, GetEventTypeCount(HIevents), HIevents, null, &ref ); #else ClassicEventHandlerUPP handler = NewClassicEventHandlerUPP( ClassicWindowEventHandler ); Host_InstallClassicWindowEventHandler( plugWindow, handler ); #endif // get window rect Rect windowBounds; GetWindowPortBounds( window, &windowBounds ); #if USE_NIBS // get text edit controls which were created from the nib #elif TARGET_API_MAC_CARBON // create header ControlID id; Rect bounds = windowBounds; InsetRect( &bounds, -1, -1 ); bounds.bottom = bounds.top + kHeaderHeight +1; CreateWindowHeaderControl( window, &bounds, false, &hexWindow->header ); id.id = 0; id.signature = kHeaderSignature; SetControlID( hexWindow->header, &id ); // set up header font information ControlFontStyleRec fontStyle = {}; fontStyle.flags = kControlUseFontMask + kControlUseJustMask; fontStyle.font = kControlFontSmallSystemFont; fontStyle.just = teJustLeft; // create header static text controls GetWindowPortBounds( window, &windowBounds ); SetRect( &bounds, windowBounds.left +4, 2, (windowBounds.right - windowBounds.left) /2, kHeaderHeight -2 ); CreateStaticTextControl( window, &bounds, CFSTR("left side"), &fontStyle, &hexWindow->left ); id.id = 0; id.signature = kLeftTextSignature; SetControlID( hexWindow->left, &id ); fontStyle.just = teJustRight; SetRect( &bounds, (windowBounds.right - windowBounds.left) /2, 2, windowBounds.right -4, kHeaderHeight -2 ); CreateStaticTextControl( window, &bounds, CFSTR("right side"), &fontStyle, &hexWindow->right ); id.id = 0; id.signature = kRightTextSignature; SetControlID( hexWindow->right, &id ); // SetHeaderText(); // embed text controls within header EmbedControl( hexWindow->left, hexWindow->header ); EmbedControl( hexWindow->right, hexWindow->header ); #else // only create a scroll bar, draw everything else DrawWindow( window ); #endif #if TARGET_API_MAC_CARBON // install blinking timer EventLoopTimerUPP timerProc = NewEventLoopTimerUPP( BlinkInsertionPoint ); InstallEventLoopTimer( GetMainEventLoop(), 0, kEventDurationSecond /3, timerProc, window, &hexWindow->timer ); #endif // set scrollbar globals hexWindow->UpdateHexInfo(); // add menu to menu bar Host_AppendMenuToBar( plug, kEditorMenu ); // show window ShowWindow( window ); // this is the plug's responsibility SelectWindow( window ); BringToFront( window ); return error; } \ No newline at end of file diff --git a/Hex Editor/Hex Editor.h b/Hex Editor/Hex Editor.h index b7e2b29..36048c2 100644 --- a/Hex Editor/Hex Editor.h +++ b/Hex Editor/Hex Editor.h @@ -1,5 +1,9 @@ #if !TARGET_API_MAC_OS8 - #include + #if defined(__APPLE_CC__) // compiling with gcc + #include + #else // compiling with CodeWarrior, __MWERKS__ + #include + #endif #endif #ifndef _ResKnife_Plug_ diff --git a/NovaTools/DataSource.h b/NovaTools/DataSource.h index 1788c29..5e7b6a9 100755 --- a/NovaTools/DataSource.h +++ b/NovaTools/DataSource.h @@ -13,8 +13,11 @@ - (void)setData:(NSMutableDictionary *)newData; - (void)setString:(NSString *)newData forResID:(int)resID; - (void)parseForString:(NSString *)string sorted:(BOOL)sort; +- (void)parseForString:(NSString *)string withinRange:(NSRange)resIDRange sorted:(BOOL)sort; - (id)objectValueForResID:(NSNumber *)resID; - (NSString *)stringValueForResID:(NSNumber *)resID; ++ (NSNumber *)resIDFromStringValue:(NSString *)string; ++ (NSString *)resNameFromStringValue:(NSString *)string; // NSComboBoxDataSource informal protocol - (id)comboBox:(NSComboBox *)comboBox objectValueForItemAtIndex:(int)index; diff --git a/NovaTools/DataSource.m b/NovaTools/DataSource.m index 71fd06e..9db886b 100755 --- a/NovaTools/DataSource.m +++ b/NovaTools/DataSource.m @@ -1,5 +1,6 @@ #import "DataSource.h" #import "ResKnifeResourceProtocol.h" +#import "NSNumber-Range.h" @implementation DataSource @@ -16,7 +17,7 @@ data = [[NSMutableDictionary alloc] init]; { id resource; - NSArray *resources = [NSClassFromString(@"Resource") allResourcesOfType:type inDocument:nil]; + NSArray *resources = [NSClassFromString(@"Resource") allResourcesOfType:type inDocument:nil]; // nil document will search in ANY open document for the correct resource NSEnumerator *enumerator = [resources objectEnumerator]; while( resource = [enumerator nextObject] ) [data setObject:[resource name] forKey:[resource resID]]; @@ -27,6 +28,7 @@ - (void)dealloc { + [type release]; [data release]; [parsed release]; [super dealloc]; @@ -51,16 +53,22 @@ } - (void)parseForString:(NSString *)string sorted:(BOOL)sort +{ + [self parseForString:string withinRange:NSMakeRange(-32767, 65536) sorted:sort]; +} + +- (void)parseForString:(NSString *)string withinRange:(NSRange)resIDRange sorted:(BOOL)sort { NSNumber *resID; + NSString *trimmedString = [DataSource resNameFromStringValue:string]; NSEnumerator *enumerator = [[data allKeys] objectEnumerator]; [parsed removeAllObjects]; while( resID = [enumerator nextObject] ) { NSString *value = [data objectForKey:resID]; - NSRange range = [value rangeOfString:string options:NSCaseInsensitiveSearch]; - if( range.location != NSNotFound || [string isEqualToString:@""] ) - [parsed addObject:[NSString stringWithFormat:@"%@ {%@}", value, resID]]; + NSRange range = [value rangeOfString:trimmedString options:NSCaseInsensitiveSearch]; + if( ((range.location != NSNotFound && range.length != 0) || [trimmedString isEqualToString:@""]) && [resID isBoundedByRange:resIDRange] ) + [parsed addObject:[self stringValueForResID:resID]]; } if( sort ) [parsed sortUsingSelector:@selector(caseInsensitiveCompare:)]; } @@ -72,7 +80,43 @@ - (NSString *)stringValueForResID:(NSNumber *)resID { - return [NSString stringWithFormat:@"%@ {%@}", [data objectForKey:resID], resID]; + if( resID && [data objectForKey:resID] ) + return [NSString stringWithFormat:@"%@ {%@}", [data objectForKey:resID], resID]; + else if( [resID isEqualToNumber:[NSNumber numberWithInt:-1]] ) + return @""; + else if( resID ) + return [NSString stringWithFormat:@"{%@}", resID]; + return nil; +} + ++ (NSNumber *)resIDFromStringValue:(NSString *)string +{ + NSRange span, range = NSMakeRange(0,0); + span = [string rangeOfString:@"{" options:NSBackwardsSearch]; + if( span.location != NSNotFound ) range.location = span.location +1; + else return [NSNumber numberWithInt:-1]; + span = [string rangeOfString:@"}" options:NSBackwardsSearch]; + if( span.location != NSNotFound ) range.length = span.location - range.location; + else return [NSNumber numberWithInt:-1]; + NS_DURING + NS_VALUERETURN( [[[NSNumber alloc] initWithInt:[[string substringWithRange:range] intValue]] autorelease], NSNumber* ); + NS_HANDLER + NS_VALUERETURN( nil, NSNumber* ); + NS_ENDHANDLER +} + ++ (NSString *)resNameFromStringValue:(NSString *)string +{ + NSRange range = [string rangeOfString:@"{" options:NSBackwardsSearch]; + if( range.location != NSNotFound ) + { + NS_DURING + NS_VALUERETURN( [string substringToIndex:range.location -1], NSString* ); + NS_HANDLER + NS_VALUERETURN( nil, NSString* ); + NS_ENDHANDLER + } + else return string; } /* NSComboBox Informal Prototype Implementation */ @@ -89,21 +133,16 @@ /* Combo Box Delegate Methods */ -- (void)controlTextDidBeginEditing:(NSNotification *)notification -{ - [self parseForString:[[notification object] stringValue] sorted:YES]; - [[notification object] reloadData]; -} - -- (void)controlTextDidChange:(NSNotification *)notification -{ - [self parseForString:[[notification object] stringValue] sorted:YES]; - [[notification object] reloadData]; -} - - (BOOL)control:(NSControl *)control isValidObject:(id)object { return [parsed containsObject:object]; } +/* Description */ + +- (NSString *)description +{ + return [NSString stringWithFormat:@"\nType: %@\nData: %@\nParsed Data: %@\n", type, [data description], [parsed description]]; +} + @end diff --git a/NovaTools/English.lproj/Resource Types.strings b/NovaTools/English.lproj/Resource Types.strings index ee3af32..f492db8 100644 Binary files a/NovaTools/English.lproj/Resource Types.strings and b/NovaTools/English.lproj/Resource Types.strings differ diff --git a/NovaTools/NovaWindowController.h b/NovaTools/NovaWindowController.h index c4bb0ae..cf81065 100644 --- a/NovaTools/NovaWindowController.h +++ b/NovaTools/NovaWindowController.h @@ -1,18 +1,27 @@ #import +#import #import "Structs.h" #import "DataSource.h" #import "ResKnifePluginProtocol.h" #import "ResKnifeResourceProtocol.h" +#define localCenter [NSNotificationCenter defaultCenter] + @interface NovaWindowController : NSWindowController { id resource; NSUndoManager *undoManager; +// NSNotificationCenter *localCenter; + NSBundle *plugBundle; + DataSource *descriptionDataSource; DataSource *governmentDataSource; + DataSource *pictureDataSource; DataSource *planetDataSource; DataSource *shipDataSource; + DataSource *soundDataSource; + DataSource *spinDataSource; } - (void)setResource:(id )newResource; @@ -20,5 +29,14 @@ - (IBAction)toggleResID:(id)sender; - (void)resourceNameDidChange:(NSNotification *)notification; +- (void)saveSheetDidClose:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo; +- (void)invalidValuesSheetDidClose:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo; @end + +@interface NovaWindowController (AbstractNovaMethods) + +- (NSDictionary *)validateValues; +- (void)saveResource; + +@end \ No newline at end of file diff --git a/NovaTools/NovaWindowController.m b/NovaTools/NovaWindowController.m index 659ef33..cc4848a 100644 --- a/NovaTools/NovaWindowController.m +++ b/NovaTools/NovaWindowController.m @@ -12,7 +12,7 @@ id oldSelf = self; NSData *classData = [[(id )newResource type] dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]; NSString *className = [[[NSString stringWithCString:[classData bytes] length:[classData length]] capitalizedString] stringByAppendingString:@"WindowController"]; - if( [className isEqualToString:@"Yea(R)WindowController"] ) className = @"YearWindowController"; + if( [className isEqualToString:@"Yea(R)WindowController"] ) className = @"YearWindowController"; // lossy conversion turns ¨ into (R), so i have to special-case Ø‘Š¨ self = [[NSClassFromString(className) alloc] initWithResource:newResource]; [oldSelf release]; if( !self ) return nil; @@ -20,6 +20,9 @@ // do global stuff here resource = [(id)newResource retain]; undoManager = [[NSUndoManager alloc] init]; +// localCenter = [[NSNotificationCenter alloc] init]; + plugBundle = [NSBundle bundleForClass:[self class]]; +// plugBundle = [NSBundle bundleWithIdentifier:@"au.com.sutherland-studios.resknife.novatools"]; // load the window from the nib file and set it's title [self window]; // implicitly loads nib @@ -35,29 +38,26 @@ - (void)dealloc { +// [localCenter release]; [[NSNotificationCenter defaultCenter] removeObserver:self]; [(id)resource autorelease]; [undoManager release]; - [shipDataSource release]; + [shipDataSource release]; // bug: release all data sources [super dealloc]; } - (void)windowDidLoad { - NSBundle *plugBundle = [NSBundle bundleWithIdentifier:@"au.com.sutherland-studios.resknife.novatools"]; - -/* NSLog( @"path: %@", [[NSBundle mainBundle] pathForAuxiliaryExecutable:@"NovaTools"] ); - NSLog( @"path: %@", [[NSBundle mainBundle] pathForResource:@"NovaTools" ofType:nil] ); - NSLog( @"path: %@", [[NSBundle mainBundle] pathForResource:@"NovaTools" ofType:nil inDirectory:@"PlugIns"] ); - NSLog( @"path: %@", [[[NSBundle mainBundle] builtInPlugInsPath] stringByAppendingPathComponent:@"NovaTools.plugin"] ); - NSLog( @"path: %@", [[NSBundle bundleWithIdentifier:@"au.com.sutherland-studios.resknife.novatools"] bundlePath] ); -*/ [super windowDidLoad]; // create the data sources (here because this is called just before they are applied to the combo boxes) + descriptionDataSource = [[DataSource alloc] initForType:[plugBundle localizedStringForKey:@"desc" value:@"" table:@"Resource Types"]]; governmentDataSource = [[DataSource alloc] initForType:[plugBundle localizedStringForKey:@"govt" value:@"" table:@"Resource Types"]]; + pictureDataSource = [[DataSource alloc] initForType:[plugBundle localizedStringForKey:@"PICT" value:@"" table:@"Resource Types"]]; planetDataSource = [[DataSource alloc] initForType:[plugBundle localizedStringForKey:@"spob" value:@"" table:@"Resource Types"]]; shipDataSource = [[DataSource alloc] initForType:[plugBundle localizedStringForKey:@"ship" value:@"" table:@"Resource Types"]]; + soundDataSource = [[DataSource alloc] initForType:[plugBundle localizedStringForKey:@"snd" value:@"" table:@"Resource Types"]]; + spinDataSource = [[DataSource alloc] initForType:[plugBundle localizedStringForKey:@"spin" value:@"" table:@"Resource Types"]]; // we don't want this notification until we have a window! [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(resourceNameDidChange:) name:ResourceNameDidChangeNotification object:resource]; @@ -70,6 +70,40 @@ return undoManager; } +- (BOOL)windowShouldClose:(id)sender +{ + if( [[self window] isDocumentEdited] ) + { + NSDictionary *errorValues = [self validateValues]; + NSArray *fields = [errorValues allKeys]; + NSArray *descriptions = [errorValues allValues]; + switch( [errorValues count] ) + { + case 0: + NSBeginAlertSheet( @"Do you want to save the changes you made to this resource?", @"Save", @"DonÕt Save", @"Cancel", sender, self, @selector(saveSheetDidClose:returnCode:contextInfo:), nil, nil, @"Your changes will be lost if you don't save them." ); + break; + + case 1: + NSBeginAlertSheet( @"Invalid values, changes cannot be saved.", @"Cancel", @"Discard Changes", nil, sender, self, @selector(invalidValuesSheetDidClose:returnCode:contextInfo:), nil, nil, @"An invalid value has been given for one of the resource's items. The following field has it's value set incorrectly:\n\n%@: %@", [fields objectAtIndex:0], [descriptions objectAtIndex:0] ); + break; + + case 2: + NSBeginAlertSheet( @"Invalid values, changes cannot be saved.", @"Cancel", @"Discard Changes", nil, sender, self, @selector(invalidValuesSheetDidClose:returnCode:contextInfo:), nil, nil, @"There are invalid values given for a couple of the resource's items. The following fields have their values set incorrectly:\n\n%@: %@\n%@: %@", [fields objectAtIndex:0], [descriptions objectAtIndex:0], [fields objectAtIndex:1], [descriptions objectAtIndex:1] ); + break; + + case 3: + NSBeginAlertSheet( @"Invalid values, changes cannot be saved.", @"Cancel", @"Discard Changes", nil, sender, self, @selector(invalidValuesSheetDidClose:returnCode:contextInfo:), nil, nil, @"There are invalid values given for three of the resource's items. The following fields have their values set incorrectly:\n\n%@: %@\n%@: %@\n%@: %@", [fields objectAtIndex:0], [descriptions objectAtIndex:0], [fields objectAtIndex:1], [descriptions objectAtIndex:1], [fields objectAtIndex:2], [descriptions objectAtIndex:2] ); + break; + + default: + NSBeginAlertSheet( @"Invalid values, changes cannot be saved.", @"Cancel", @"Discard Changes", nil, sender, self, @selector(invalidValuesSheetDidClose:returnCode:contextInfo:), nil, nil, @"There are invalid values given for many of the resource's items. The following fields have their values set incorrectly:\n\n%@: %@\n%@: %@\n%@: %@\nplus others.", [fields objectAtIndex:0], [descriptions objectAtIndex:0], [fields objectAtIndex:1], [descriptions objectAtIndex:1], [fields objectAtIndex:2], [descriptions objectAtIndex:2] ); + break; + } + return NO; + } + else return YES; +} + - (void)setResource:(id )newResource { id old = resource; @@ -101,4 +135,35 @@ else [[self window] setTitle:prefix]; } +- (void)saveSheetDidClose:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo +{ + switch( returnCode ) + { + case NSAlertDefaultReturn: // save + [self saveResource]; + [[self window] close]; + break; + + case NSAlertAlternateReturn: // don't save + [[self window] close]; + break; + + case NSAlertOtherReturn: // cancel + break; + } +} + +- (void)invalidValuesSheetDidClose:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo +{ + switch( returnCode ) + { + case NSAlertDefaultReturn: // cancel + break; + + case NSAlertAlternateReturn: // discard changes + [[self window] close]; + break; + } +} + @end diff --git a/NovaTools/Structs.h b/NovaTools/Structs.h index b1dd518..fc2e22d 100644 --- a/NovaTools/Structs.h +++ b/NovaTools/Structs.h @@ -576,9 +576,9 @@ typedef struct NebuRec typedef struct BoomRec { - short FrameAdvance; - short SoundIndex; - short GraphicIndex; + short FrameAdvance; // 100 = normal speed, less is slower, higher faster + short SoundIndex; // 0-63 index, mapping to 300-363 resID + short GraphicIndex; // 0-63 index, mapping to 400-463 resID } BoomRec; typedef struct FletRec diff --git a/NovaTools/boom/BoomWindowController.h b/NovaTools/boom/BoomWindowController.h index b86ec1c..107b8a2 100644 --- a/NovaTools/boom/BoomWindowController.h +++ b/NovaTools/boom/BoomWindowController.h @@ -1,8 +1,35 @@ #import #import "NovaWindowController.h" +enum +{ + kMinSpinID = 400, + kSpinIDRange = 64, + kMinSoundID = 300, + kSoundIDRange = 64 +}; + @interface BoomWindowController : NovaWindowController { BoomRec *boomRec; + + IBOutlet NSImageView *imageWell; + IBOutlet NSComboBox *graphicsField; + IBOutlet NSComboBox *soundField; + IBOutlet NSTextField *frameRateField; + IBOutlet NSButton *soundButton; + IBOutlet NSButton *playButton; + + // stuff + NSNumber *image; + NSNumber *sound; + NSNumber *frameRate; + BOOL silent; } + +- (void)update; +- (void)controlTextDidChange:(NSNotification *)notification; +- (IBAction)toggleSilence:(id)sender; +- (IBAction)playSound:(id)sender; + @end diff --git a/NovaTools/boom/BoomWindowController.m b/NovaTools/boom/BoomWindowController.m index 74675ac..2bf4ff6 100644 --- a/NovaTools/boom/BoomWindowController.m +++ b/NovaTools/boom/BoomWindowController.m @@ -2,12 +2,18 @@ @implementation BoomWindowController -- (id)initWithResource:(id)newResource +- (id)initWithResource:(id )newResource { self = [self initWithWindowNibName:@"boom"]; if( !self ) return nil; - boomRec = (BoomRec *)calloc(1,sizeof(BoomRec)); + boomRec = (BoomRec *) calloc( 1, sizeof(BoomRec) ); + [[newResource data] getBytes:boomRec]; + silent = (boomRec->SoundIndex == -1); + if( boomRec->FrameAdvance == 0 ) boomRec->FrameAdvance = 100; + image = [[NSNumber alloc] initWithShort:boomRec->GraphicIndex +400]; + sound = [[NSNumber alloc] initWithShort:boomRec->SoundIndex +300 + (silent? 1:0)]; + frameRate = [[NSNumber alloc] initWithShort:boomRec->FrameAdvance]; return self; } @@ -15,7 +21,128 @@ - (void)windowDidLoad { [super windowDidLoad]; + + // set combo box data sources + [graphicsField setDelegate:spinDataSource]; + [graphicsField setDataSource:spinDataSource]; + [soundField setDelegate:soundDataSource]; + [soundField setDataSource:soundDataSource]; + + // set notifications for ending editing on a combo box + [localCenter addObserver:self selector:@selector(comboBoxWillPopUp:) name:NSComboBoxWillPopUpNotification object:nil]; + [localCenter addObserver:self selector:@selector(controlTextDidChange:) name:NSComboBoxWillDismissNotification object:nil]; + [localCenter addObserver:self selector:@selector(controlTextDidChange:) name:NSControlTextDidChangeNotification object:nil]; + + [self update]; [self showWindow:self]; } +- (void)update +{ + // graphics + [graphicsField setObjectValue:[spinDataSource stringValueForResID:image]]; +// [spinDataSource parseForString:[graphicsField stringValue] withinRange:NSMakeRange(kMinSpinID, kSpinIDRange) sorted:NO]; + [frameRateField setObjectValue:frameRate]; + + // sound + [soundField setObjectValue:[soundDataSource stringValueForResID:sound]]; +// [soundDataSource parseForString:[soundField stringValue] withinRange:NSMakeRange(kMinSoundID, kSoundIDRange) sorted:NO]; + [soundButton setState:!silent]; + [soundField setEnabled:!silent]; + [playButton setEnabled:!silent]; + + // image well + [imageWell setImage:[[[NSImage alloc] initWithData:[(id )[NSClassFromString(@"Resource") resourceOfType:[plugBundle localizedStringForKey:@"spin" value:@"" table:@"Resource Types"] andID:image inDocument:nil] data]] autorelease]]; +} + +- (void)comboBoxWillPopUp:(NSNotification *)notification +{ + id sender = [notification object]; + if( sender == graphicsField ) + [spinDataSource parseForString:[sender stringValue] withinRange:NSMakeRange(kMinSpinID, kSpinIDRange) sorted:YES]; + else if( sender == soundField ) + [soundDataSource parseForString:[sender stringValue] withinRange:NSMakeRange(kMinSoundID, kSoundIDRange) sorted:YES]; + + if( [sender class] == NSClassFromString(@"NSComboBox") ) + [sender reloadData]; +} + +- (void)controlTextDidChange:(NSNotification *)notification +{ + id sender = [notification object]; + if( sender == graphicsField && [sender stringValue] ) + { + id old = image; + image = [[DataSource resIDFromStringValue:[sender stringValue]] retain]; + if( ![image isEqualToNumber:old] ) [resource touch]; + [old release]; + } + else if( sender == soundField && [sender stringValue] ) + { + id old = sound; + sound = [[DataSource resIDFromStringValue:[sender stringValue]] retain]; + if( ![sound isEqualToNumber:old] ) [resource touch]; + [old release]; + } + else if( sender == frameRateField ) + { + id old = frameRate; + frameRate = [[NSNumber alloc] initWithInt:[sender intValue]]; + if( ![frameRate isEqualToNumber:old] ) [resource touch]; + [old release]; + } + + // hack to simply & easily parse combo boxes + [self comboBoxWillPopUp:notification]; + [self setDocumentEdited:[resource isDirty]]; +} + +- (IBAction)toggleSilence:(id)sender +{ + silent = ![soundButton state]; + [soundField setEnabled:!silent]; + [playButton setEnabled:!silent]; + [resource touch]; + [self setDocumentEdited:YES]; +} + +- (IBAction)playSound:(id)sender +{ + NSData *data = [(id )[NSClassFromString(@"Resource") resourceOfType:[plugBundle localizedStringForKey:@"snd" value:@"" table:@"Resource Types"] andID:sound inDocument:nil] data]; + if( data && [data length] != 0 ) + { + SndListPtr sndPtr = (SndListPtr) [data bytes]; + SndPlay( nil, &sndPtr, false ); + } + else NSBeep(); +} + +- (NSDictionary *)validateValues +{ + NSMutableDictionary *errorValues = [NSMutableDictionary dictionary]; + + // get current values + boomRec->GraphicIndex = [image shortValue] -400; + boomRec->SoundIndex = [sound shortValue] -300; + boomRec->FrameAdvance = [frameRate shortValue]; + if( silent ) boomRec->SoundIndex = -1; + + // verify values are valid + if( boomRec->GraphicIndex < 0 || boomRec->GraphicIndex > 63 ) + [errorValues setObject:@"must match a spin resource with ID between 400 and 463." forKey:@"Graphics"]; + if( boomRec->SoundIndex < -1 || boomRec->SoundIndex > 63 ) + [errorValues setObject:@"must match a sound resource with ID between 300 and 363." forKey:@"Sound"]; + if( boomRec->FrameAdvance < 1 || boomRec->FrameAdvance > 1000 ) + [errorValues setObject:@"cannot be below 0% or above 1000%." forKey:@"Frame Advance"]; + + // all values fell within acceptable range + return errorValues; +} + +- (void)saveResource +{ + // save new data into resource structure (should have already been validated, and boomRec filled out correctly) + [resource setData:[NSData dataWithBytes:boomRec length:sizeof(boomRec)]]; +} + @end diff --git a/NovaTools/boom/English.lproj/boom.nib/classes.nib b/NovaTools/boom/English.lproj/boom.nib/classes.nib index 966330e..a853176 100644 --- a/NovaTools/boom/English.lproj/boom.nib/classes.nib +++ b/NovaTools/boom/English.lproj/boom.nib/classes.nib @@ -1,8 +1,17 @@ { IBClasses = ( { + ACTIONS = {playSound = id; toggleSilence = id; }; CLASS = BoomWindowController; LANGUAGE = ObjC; + OUTLETS = { + frameRateField = NSTextField; + graphicsField = NSComboBox; + imageWell = NSImageView; + playButton = NSButton; + soundButton = NSButton; + soundField = NSComboBox; + }; SUPERCLASS = NovaWindowController; }, {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, diff --git a/NovaTools/boom/English.lproj/boom.nib/info.nib b/NovaTools/boom/English.lproj/boom.nib/info.nib index b4d5b71..3cb3257 100644 --- a/NovaTools/boom/English.lproj/boom.nib/info.nib +++ b/NovaTools/boom/English.lproj/boom.nib/info.nib @@ -3,10 +3,14 @@ IBDocumentLocation - 120 159 356 240 0 0 1152 848 + 161 150 356 240 0 0 1600 1002 IBFramework Version - 263.2 + 248.0 + IBOpenObjects + + 5 + IBSystem Version - 5Q125 + 5S66 diff --git a/NovaTools/boom/English.lproj/boom.nib/objects.nib b/NovaTools/boom/English.lproj/boom.nib/objects.nib index dcacd93..663b5b6 100644 Binary files a/NovaTools/boom/English.lproj/boom.nib/objects.nib and b/NovaTools/boom/English.lproj/boom.nib/objects.nib differ diff --git a/NovaTools/char/CharWindowController.h b/NovaTools/char/CharWindowController.h index 7e7b5d5..775d390 100644 --- a/NovaTools/char/CharWindowController.h +++ b/NovaTools/char/CharWindowController.h @@ -1,17 +1,25 @@ #import #import "NovaWindowController.h" -#define cashField [goodiesForm cellAtIndex:0] -#define killsField [goodiesForm cellAtIndex:1] -#define prefixField [timeForm cellAtIndex:0] -#define suffixField [timeForm cellAtIndex:1] -#define statusField1 [statusForm cellAtIndex:0] -#define statusField2 [statusForm cellAtIndex:1] -#define statusField3 [statusForm cellAtIndex:2] -#define statusField4 [statusForm cellAtIndex:3] +#define cashField [goodiesForm cellAtIndex:0] +#define killsField [goodiesForm cellAtIndex:1] +#define prefixField [timeForm cellAtIndex:0] +#define suffixField [timeForm cellAtIndex:1] +#define statusField1 [statusForm cellAtIndex:0] +#define statusField2 [statusForm cellAtIndex:1] +#define statusField3 [statusForm cellAtIndex:2] +#define statusField4 [statusForm cellAtIndex:3] +#define introDelayField1 [introDelayForm cellAtIndex:0] +#define introDelayField2 [introDelayForm cellAtIndex:1] +#define introDelayField3 [introDelayForm cellAtIndex:2] +#define introDelayField4 [introDelayForm cellAtIndex:3] +#define onStartField [ncbForm cellAtIndex:0] @interface CharWindowController : NovaWindowController { + CharRec *charRec; + + IBOutlet NSButton *principalCharButton; IBOutlet NSComboBox *shipField; IBOutlet NSForm *goodiesForm; @@ -34,6 +42,20 @@ IBOutlet NSComboBox *governmentField3; IBOutlet NSComboBox *governmentField4; + IBOutlet NSComboBox *introPictField1; + IBOutlet NSComboBox *introPictField2; + IBOutlet NSComboBox *introPictField3; + IBOutlet NSComboBox *introPictField4; + IBOutlet NSForm *introDelayForm; + IBOutlet NSComboBox *introTextField; + IBOutlet NSImageView *introImageView; + IBOutlet NSTextView *introTextView; + + IBOutlet NSForm *ncbForm; + + // char + BOOL principalChar; + // Initial Goodies NSNumber *ship; NSNumber *cash; @@ -59,10 +81,27 @@ NSNumber *government2; NSNumber *government3; NSNumber *government4; + + // Introduction + NSNumber *introText; + NSNumber *introPict1; + NSNumber *introPict2; + NSNumber *introPict3; + NSNumber *introPict4; + NSNumber *introDelay1; + NSNumber *introDelay2; + NSNumber *introDelay3; + NSNumber *introDelay4; + NSTimer *introPictTimer; + + // Nova Control Bits + NSString *onStart; } - (void)update; - (IBAction)editDate:(id)sender; - (IBAction)stepDate:(id)sender; +- (void)comboBoxWillPopUp:(NSNotification *)notification; +- (void)controlTextDidChange:(NSNotification *)notification; @end diff --git a/NovaTools/char/CharWindowController.m b/NovaTools/char/CharWindowController.m index cdd8efe..bd3712b 100644 --- a/NovaTools/char/CharWindowController.m +++ b/NovaTools/char/CharWindowController.m @@ -2,47 +2,57 @@ @implementation CharWindowController -- (id)initWithResource:(id)newResource +- (id)initWithResource:(id )newResource { self = [self initWithWindowNibName:@"char"]; if( !self ) return nil; // load data from resource - ship = [[NSNumber alloc] initWithShort:128]; - cash = [[NSNumber alloc] initWithLong:10000]; - kills = [[NSNumber alloc] initWithUnsignedLong:0]; - - date = [[NSCalendarDate date] retain]; - prefix = [[NSString alloc] init]; - suffix = [[NSString alloc] init]; - - start1 = [[NSNumber alloc] initWithShort:128]; - start2 = [[NSNumber alloc] initWithShort:129]; - start3 = [[NSNumber alloc] initWithShort:130]; - start4 = [[NSNumber alloc] initWithShort:131]; - - status1 = [[NSNumber alloc] initWithShort:0]; - status2 = [[NSNumber alloc] initWithShort:0]; - status3 = [[NSNumber alloc] initWithShort:0]; - status4 = [[NSNumber alloc] initWithShort:0]; - government1 = [[NSNumber alloc] initWithShort:128]; - government2 = [[NSNumber alloc] initWithShort:129]; - government3 = [[NSNumber alloc] initWithShort:130]; - government4 = [[NSNumber alloc] initWithShort:131]; - + charRec = (CharRec *) calloc( 1, sizeof(CharRec) ); + [[newResource data] getBytes:charRec]; + principalChar = charRec->Flags & 0x0001; + ship = [[NSNumber alloc] initWithShort:charRec->startShipType]; // resID + cash = [[NSNumber alloc] initWithLong:charRec->startCash]; + kills = [[NSNumber alloc] initWithShort:charRec->startKills]; + date = [[NSCalendarDate alloc] initWithYear:charRec->startYear month:charRec->startMonth day:charRec->startDay hour:0 minute:0 second:0 timeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]]; + prefix = [[NSString alloc] initWithCString:charRec->Prefix length:16]; + suffix = [[NSString alloc] initWithCString:charRec->Suffix length:16]; + start1 = [[NSNumber alloc] initWithShort:charRec->startSystem[0]]; + start2 = [[NSNumber alloc] initWithShort:charRec->startSystem[1]]; + start3 = [[NSNumber alloc] initWithShort:charRec->startSystem[2]]; + start4 = [[NSNumber alloc] initWithShort:charRec->startSystem[3]]; + status1 = [[NSNumber alloc] initWithShort:charRec->startStatus[0]]; + status2 = [[NSNumber alloc] initWithShort:charRec->startStatus[1]]; + status3 = [[NSNumber alloc] initWithShort:charRec->startStatus[2]]; + status4 = [[NSNumber alloc] initWithShort:charRec->startStatus[3]]; + government1 = [[NSNumber alloc] initWithShort:charRec->startGovt[0]]; + government2 = [[NSNumber alloc] initWithShort:charRec->startGovt[1]]; + government3 = [[NSNumber alloc] initWithShort:charRec->startGovt[2]]; + government4 = [[NSNumber alloc] initWithShort:charRec->startGovt[3]]; + introText = [[NSNumber alloc] initWithShort:charRec->introTextID]; + introPict1 = [[NSNumber alloc] initWithShort:charRec->introPictID[0]]; + introPict2 = [[NSNumber alloc] initWithShort:charRec->introPictID[1]]; + introPict3 = [[NSNumber alloc] initWithShort:charRec->introPictID[2]]; + introPict4 = [[NSNumber alloc] initWithShort:charRec->introPictID[3]]; + introDelay1 = [[NSNumber alloc] initWithShort:charRec->introPictDelay[0]]; + introDelay2 = [[NSNumber alloc] initWithShort:charRec->introPictDelay[1]]; + introDelay3 = [[NSNumber alloc] initWithShort:charRec->introPictDelay[2]]; + introDelay4 = [[NSNumber alloc] initWithShort:charRec->introPictDelay[3]]; + onStart = [[NSString alloc] initWithCString:charRec->OnStart length:256]; + return self; } - (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; + // bug: release everything [super dealloc]; } - (void)windowDidLoad { [super windowDidLoad]; - + // set combo box data sources [shipField setDelegate:shipDataSource]; [shipField setDataSource:shipDataSource]; @@ -62,17 +72,20 @@ [governmentField3 setDataSource:governmentDataSource]; [governmentField4 setDelegate:governmentDataSource]; [governmentField4 setDataSource:governmentDataSource]; + [introPictField1 setDelegate:pictureDataSource]; + [introPictField1 setDataSource:pictureDataSource]; + [introPictField2 setDelegate:pictureDataSource]; + [introPictField2 setDataSource:pictureDataSource]; + [introPictField3 setDelegate:pictureDataSource]; + [introPictField3 setDataSource:pictureDataSource]; + [introPictField4 setDelegate:pictureDataSource]; + [introPictField4 setDataSource:pictureDataSource]; + [introTextField setDataSource:descriptionDataSource]; // set notifications for ending editing on a combo box - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(controlTextDidEndEditing:) name:NSControlTextDidEndEditingNotification object:shipField]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(controlTextDidEndEditing:) name:NSControlTextDidEndEditingNotification object:startField1]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(controlTextDidEndEditing:) name:NSControlTextDidEndEditingNotification object:startField2]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(controlTextDidEndEditing:) name:NSControlTextDidEndEditingNotification object:startField3]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(controlTextDidEndEditing:) name:NSControlTextDidEndEditingNotification object:startField4]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(controlTextDidEndEditing:) name:NSControlTextDidEndEditingNotification object:governmentField1]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(controlTextDidEndEditing:) name:NSControlTextDidEndEditingNotification object:governmentField2]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(controlTextDidEndEditing:) name:NSControlTextDidEndEditingNotification object:governmentField3]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(controlTextDidEndEditing:) name:NSControlTextDidEndEditingNotification object:governmentField4]; + [localCenter addObserver:self selector:@selector(comboBoxWillPopUp:) name:NSComboBoxWillPopUpNotification object:nil]; + [localCenter addObserver:self selector:@selector(controlTextDidChange:) name:NSComboBoxWillDismissNotification object:nil]; + [localCenter addObserver:self selector:@selector(controlTextDidChange:) name:NSControlTextDidChangeNotification object:nil]; // finally, show the window [self update]; @@ -81,9 +94,11 @@ - (void)update { + // principal character + [principalCharButton setState:principalChar]; + // initial goodies [shipField setObjectValue:[shipDataSource stringValueForResID:ship]]; - [shipDataSource parseForString:[shipField stringValue] sorted:NO]; [cashField setObjectValue:cash]; [killsField setObjectValue:kills]; @@ -97,9 +112,50 @@ [prefixField setStringValue:prefix]; [suffixField setStringValue:suffix]; - // starting location - [startField1 setObjectValue:[shipDataSource stringValueForResID:start1]]; - [shipDataSource parseForString:[shipField stringValue] sorted:NO]; + // starting locations + if( [start1 isEqualToNumber:[NSNumber numberWithInt:-1]] ) [startField1 setObjectValue:nil]; + else [startField1 setObjectValue:[planetDataSource stringValueForResID:start1]]; + if( [start2 isEqualToNumber:[NSNumber numberWithInt:-1]] ) [startField2 setObjectValue:nil]; + else [startField2 setObjectValue:[planetDataSource stringValueForResID:start2]]; + if( [start3 isEqualToNumber:[NSNumber numberWithInt:-1]] ) [startField3 setObjectValue:nil]; + else [startField3 setObjectValue:[planetDataSource stringValueForResID:start3]]; + if( [start4 isEqualToNumber:[NSNumber numberWithInt:-1]] ) [startField4 setObjectValue:nil]; + else [startField4 setObjectValue:[planetDataSource stringValueForResID:start4]]; + + // governments + [statusField1 setObjectValue:status1]; + [statusField2 setObjectValue:status2]; + [statusField3 setObjectValue:status3]; + [statusField4 setObjectValue:status4]; + if( [government1 isEqualToNumber:[NSNumber numberWithInt:-1]] ) [governmentField1 setObjectValue:nil]; + else [governmentField1 setObjectValue:[governmentDataSource stringValueForResID:government1]]; + if( [government2 isEqualToNumber:[NSNumber numberWithInt:-1]] ) [governmentField2 setObjectValue:nil]; + else [governmentField2 setObjectValue:[governmentDataSource stringValueForResID:government2]]; + if( [government3 isEqualToNumber:[NSNumber numberWithInt:-1]] ) [governmentField3 setObjectValue:nil]; + else [governmentField3 setObjectValue:[governmentDataSource stringValueForResID:government3]]; + if( [government4 isEqualToNumber:[NSNumber numberWithInt:-1]] ) [governmentField4 setObjectValue:nil]; + else [governmentField4 setObjectValue:[governmentDataSource stringValueForResID:government4]]; + + // intro text & pics + if( [introPict1 isEqualToNumber:[NSNumber numberWithInt:-1]] ) [introPictField1 setObjectValue:nil]; + else [introPictField1 setObjectValue:[governmentDataSource stringValueForResID:government1]]; + if( [introPict2 isEqualToNumber:[NSNumber numberWithInt:-1]] ) [introPictField2 setObjectValue:nil]; + else [introPictField2 setObjectValue:[governmentDataSource stringValueForResID:government2]]; + if( [introPict3 isEqualToNumber:[NSNumber numberWithInt:-1]] ) [introPictField3 setObjectValue:nil]; + else [introPictField3 setObjectValue:[governmentDataSource stringValueForResID:government3]]; + if( [introPict4 isEqualToNumber:[NSNumber numberWithInt:-1]] ) [introPictField4 setObjectValue:nil]; + else [introPictField4 setObjectValue:[governmentDataSource stringValueForResID:government4]]; + if( [introText isEqualToNumber:[NSNumber numberWithInt:-1]] ) [introTextField setObjectValue:nil]; + else [introTextField setObjectValue:[descriptionDataSource stringValueForResID:introText]]; + + { + const char *stringData = [[(id )[NSClassFromString(@"Resource") getResourceOfType:[plugBundle localizedStringForKey:@"desc" value:@"" table:@"Resource Types"] andID:introText inDocument:nil] data] bytes]; + if( stringData != NULL ) + [introTextView setString:[NSString stringWithCString:stringData]]; + } + + // ncbs + [onStartField setStringValue:onStart]; } - (IBAction)editDate:(id)sender @@ -118,38 +174,144 @@ [self update]; } -- (void)controlTextDidEndEditing:(NSNotification *)notification +- (void)comboBoxWillPopUp:(NSNotification *)notification { - if( [notification object] == shipField ) + id sender = [notification object]; + if( sender == shipField ) + [shipDataSource parseForString:[sender stringValue] sorted:YES]; + else if( sender == startField1 || sender == startField2 || sender == startField3 || sender == startField4 ) + [planetDataSource parseForString:[sender stringValue] sorted:YES]; + else if( sender == governmentField1 || sender == governmentField2 || sender == governmentField3 || sender == governmentField4 ) + [governmentDataSource parseForString:[sender stringValue] sorted:YES]; + else if( sender == introPictField1 || sender == introPictField2 || sender == introPictField3 || sender == introPictField4 ) + [pictureDataSource parseForString:[sender stringValue] sorted:YES]; + else if( sender == introTextField ) + [descriptionDataSource parseForString:[sender stringValue] sorted:YES]; + + if( [sender class] == NSClassFromString(@"NSComboBox") ) + [sender reloadData]; +} + +- (void)controlTextDidChange:(NSNotification *)notification +{ + id sender = [notification object]; + + /* ship combo box */ + + if( sender == shipField ) { id old = ship; - NSString *string = [[notification object] stringValue]; - NSRange range = [string rangeOfString:@"{" options:NSBackwardsSearch]; - range.length = [string length] - range.location++ - 2; - ship = [[NSNumber alloc] initWithInt:[[string substringWithRange:range] intValue]]; - NSLog( @"Old ship: %@ New ship: %@", old, ship ); + ship = [[DataSource resIDFromStringValue:[sender stringValue]] retain]; + if( ![ship isEqualToNumber:old] ) [resource touch]; [old release]; } - else if( [notification object] == startField1 ) + + /* planet combo boxes */ + + else if( sender == startField1 ) { id old = start1; - NSString *string = [[notification object] stringValue]; - NSRange range = [string rangeOfString:@"{" options:NSBackwardsSearch]; - range.length = [string length] - range.location++ - 2; - start1 = [[NSNumber alloc] initWithInt:[[string substringWithRange:range] intValue]]; - NSLog( @"Old start1: %@ New start1: %@", old, start1 ); + start1 = [[DataSource resIDFromStringValue:[sender stringValue]] retain]; + if( ![start1 isEqualToNumber:old] ) [resource touch]; [old release]; } - else if( [notification object] == startField2 ) + else if( sender == startField2 ) { id old = start2; - NSString *string = [[notification object] stringValue]; - NSRange range = [string rangeOfString:@"{" options:NSBackwardsSearch]; - range.length = [string length] - range.location++ - 2; - start2 = [[NSNumber alloc] initWithInt:[[string substringWithRange:range] intValue]]; - NSLog( @"Old start2: %@ New start2: %@", old, start2 ); + start2 = [[DataSource resIDFromStringValue:[sender stringValue]] retain]; + if( ![start2 isEqualToNumber:old] ) [resource touch]; [old release]; } + else if( sender == startField3 ) + { + id old = start3; + start3 = [[DataSource resIDFromStringValue:[sender stringValue]] retain]; + if( ![start3 isEqualToNumber:old] ) [resource touch]; + [old release]; + } + else if( sender == startField4 ) + { + id old = start4; + start4 = [[DataSource resIDFromStringValue:[sender stringValue]] retain]; + if( ![start4 isEqualToNumber:old] ) [resource touch]; + [old release]; + } + + /* government combo boxes */ + + else if( sender == governmentField1 ) + { + id old = government1; + government1 = [[DataSource resIDFromStringValue:[sender stringValue]] retain]; + if( ![government1 isEqualToNumber:old] ) [resource touch]; + [old release]; + } + else if( sender == governmentField2 ) + { + id old = government2; + government2 = [[DataSource resIDFromStringValue:[sender stringValue]] retain]; + if( ![government2 isEqualToNumber:old] ) [resource touch]; + [old release]; + } + else if( sender == governmentField3 ) + { + id old = government3; + government3 = [[DataSource resIDFromStringValue:[sender stringValue]] retain]; + if( ![government3 isEqualToNumber:old] ) [resource touch]; + [old release]; + } + else if( sender == governmentField4 ) + { + id old = government4; + government4 = [[DataSource resIDFromStringValue:[sender stringValue]] retain]; + if( ![government4 isEqualToNumber:old] ) [resource touch]; + [old release]; + } + + /* planet combo boxes */ + + else if( sender == introPictField1 ) + { + id old = introPict1; + introPict1 = [[DataSource resIDFromStringValue:[sender stringValue]] retain]; + if( ![introPict1 isEqualToNumber:old] ) [resource touch]; + [old release]; + } + else if( sender == introPictField2 ) + { + id old = introPict2; + introPict2 = [[DataSource resIDFromStringValue:[sender stringValue]] retain]; + if( ![introPict2 isEqualToNumber:old] ) [resource touch]; + [old release]; + } + else if( sender == introPictField3 ) + { + id old = introPict3; + introPict3 = [[DataSource resIDFromStringValue:[sender stringValue]] retain]; + if( ![introPict3 isEqualToNumber:old] ) [resource touch]; + [old release]; + } + else if( sender == introPictField4 ) + { + id old = introPict4; + introPict4 = [[DataSource resIDFromStringValue:[sender stringValue]] retain]; + if( ![introPict4 isEqualToNumber:old] ) [resource touch]; + [old release]; + } + + /* intro text combo box */ + + else if( sender == introTextField ) + { + id old = introText; + introText = [[DataSource resIDFromStringValue:[sender stringValue]] retain]; + if( ![introText isEqualToNumber:old] ) [resource touch]; + [old release]; + } + + // hack to simply & easily parse combo boxes + [self comboBoxWillPopUp:notification]; + [self setDocumentEdited:[resource isDirty]]; } @end diff --git a/NovaTools/char/English.lproj/char.nib/classes.nib b/NovaTools/char/English.lproj/char.nib/classes.nib index b83b264..e78b3e8 100644 --- a/NovaTools/char/English.lproj/char.nib/classes.nib +++ b/NovaTools/char/English.lproj/char.nib/classes.nib @@ -12,8 +12,18 @@ governmentField2 = NSComboBox; governmentField3 = NSComboBox; governmentField4 = NSComboBox; + introDelayForm = NSForm; + introImageView = NSImageView; + introPictField1 = NSComboBox; + introPictField2 = NSComboBox; + introPictField3 = NSComboBox; + introPictField4 = NSComboBox; + introTextField = NSComboBox; + introTextView = NSTextView; monthField = NSTextField; monthStepper = NSStepper; + ncbForm = NSForm; + principalChar = NSButton; shipField = NSComboBox; startField1 = NSComboBox; startField2 = NSComboBox; diff --git a/NovaTools/char/English.lproj/char.nib/info.nib b/NovaTools/char/English.lproj/char.nib/info.nib index 39dd71b..c7ca465 100644 --- a/NovaTools/char/English.lproj/char.nib/info.nib +++ b/NovaTools/char/English.lproj/char.nib/info.nib @@ -3,9 +3,9 @@ IBDocumentLocation - 30 118 356 240 0 0 1152 848 + 47 148 356 240 0 0 1600 1002 IBFramework Version - 263.2 + 248.0 IBGroupedObjects 2 @@ -20,7 +20,11 @@ IBLastGroupID 3 + IBOpenObjects + + 137 + IBSystem Version - 5Q125 + 5S66 diff --git a/NovaTools/char/English.lproj/char.nib/objects.nib b/NovaTools/char/English.lproj/char.nib/objects.nib index 644aa67..62abb7d 100644 Binary files a/NovaTools/char/English.lproj/char.nib/objects.nib and b/NovaTools/char/English.lproj/char.nib/objects.nib differ diff --git a/NovaTools/colr/ColrWindowController.m b/NovaTools/colr/ColrWindowController.m index af41ef7..6e1682b 100644 --- a/NovaTools/colr/ColrWindowController.m +++ b/NovaTools/colr/ColrWindowController.m @@ -2,7 +2,7 @@ @implementation ColrWindowController -- (id)initWithResource:(id)newResource +- (id)initWithResource:(id )newResource { self = [self initWithWindowNibName:@"colr"]; if( !self ) return nil; diff --git a/NovaTools/cron/CronWindowController.m b/NovaTools/cron/CronWindowController.m index 49457cd..c57ffe4 100644 --- a/NovaTools/cron/CronWindowController.m +++ b/NovaTools/cron/CronWindowController.m @@ -2,7 +2,7 @@ @implementation CronWindowController -- (id)initWithResource:(id)newResource +- (id)initWithResource:(id )newResource { self = [self initWithWindowNibName:@"cron"]; if( !self ) return nil; @@ -17,6 +17,16 @@ - (void)windowDidLoad { [super windowDidLoad]; + +/* [governmentField1 setDelegate:governmentDataSource]; + [governmentField1 setDataSource:governmentDataSource]; + [governmentField2 setDelegate:governmentDataSource]; + [governmentField2 setDataSource:governmentDataSource]; + [governmentField3 setDelegate:governmentDataSource]; + [governmentField3 setDataSource:governmentDataSource]; + [governmentField4 setDelegate:governmentDataSource]; + [governmentField4 setDataSource:governmentDataSource]; +*/ [self update]; [self showWindow:self]; } diff --git a/NovaTools/desc/DescWindowController.m b/NovaTools/desc/DescWindowController.m index 313d77c..73345d0 100644 --- a/NovaTools/desc/DescWindowController.m +++ b/NovaTools/desc/DescWindowController.m @@ -2,7 +2,7 @@ @implementation DescWindowController -- (id)initWithResource:(id)newResource +- (id)initWithResource:(id )newResource { self = [self initWithWindowNibName:@"desc"]; if( !self ) return nil; diff --git a/PICT Editor/PICT Editor.h b/PICT Editor/PICT Editor.h index e6df902..662a833 100644 --- a/PICT Editor/PICT Editor.h +++ b/PICT Editor/PICT Editor.h @@ -1 +1 @@ -#if !TARGET_API_MAC_OS8 #include #endif #ifndef _ResKnife_Plug_ #define _ResKnife_Plug_ 1 #include "HostCallbacks.h" #endif #ifndef _ResKnife_PictEditor_ #define _ResKnife_PictEditor_ // abbreviations #define null NULL #define Use_Nibs 0 #define Use_GWorlds 1 // Easier API call names #define GetWindowRefCon( window ) (long) GetWRefCon( window ) #define SetWindowRefCon( window, refcon ) SetWRefCon( window, refcon ) #define GetWindowTitle( window, string ) GetWTitle( window, string ) #define SetWindowTitle( window, name ) SetWTitle( window, name ) #define InvalidateRect( bounds ) InvalRect( bounds ) #define InvalidateWindowRect( window, bounds ) (OSStatus) InvalWindowRect( window, bounds ) #define RectToRegion( region, rect ) RectRgn( region, rect ) #define SetPoint( point, x, y ) SetPt( point, x, y ) #define HilightColour( colour ) HiliteColor( colour ) #define GetPortHilightColour( window, colour ) GetPortHiliteColor( window, colour ) /* Global Variables */ struct globals { // application Str255 fragName; Str255 prefsName; // system info SInt32 systemVersion; Boolean dragAvailable; Boolean translucentDrag; Boolean navAvailable; Boolean useAppearance; // colours RGBColor white; // 0xFFFF, 65535 RGBColor bgColour; // 0xEEEE, 61166 RGBColor black; // 0x0000, 0 }; /* Preferences */ struct prefs { UInt32 version; // == kPictEditorCurrentVersion, when saved to disk allows older prefs to be read in UInt8 GWorldDepth; }; /*** CONSTANTS ***/ const UInt32 kPictEditorCurrentVersion = 0x00030003; const UInt16 kHeaderHeight = 20; const UInt16 kScrollBarWidth = 16; const UInt16 kMinimumWindowWidth = 384; const UInt16 kDefaultWindowWidth = kMinimumWindowWidth; const UInt16 kMinimumWindowHeight = 256 + kHeaderHeight; const UInt16 kDefaultWindowHeight = kMinimumWindowHeight; const UInt32 kHeaderSignature = FOUR_CHAR_CODE('head'); const UInt32 kLeftTextSignature = FOUR_CHAR_CODE('left'); const UInt32 kRightTextSignature = FOUR_CHAR_CODE('rght'); const UInt32 kScrollbarSignature = FOUR_CHAR_CODE('scrl'); // MacOS versions const SInt32 kMacOSSevenPointOne = 0x00000710; const SInt32 kMacOSSevenPointFivePointFive = 0x00000755; const SInt32 kMacOSEight = 0x00000800; const SInt32 kMacOSEightPointFive = 0x00000850; const SInt32 kMacOSEightPointSix = 0x00000860; const SInt32 kMacOSNine = 0x00000900; const SInt32 kMacOSNinePointOne = 0x00000910; const SInt32 kMacOSTen = 0x00001000; const SInt32 kMacOS71 = kMacOSSevenPointOne; const SInt32 kMacOS755 = kMacOSSevenPointFivePointFive; const SInt32 kMacOS8 = kMacOSEight; const SInt32 kMacOS85 = kMacOSEightPointFive; const SInt32 kMacOS86 = kMacOSEightPointSix; const SInt32 kMacOS9 = kMacOSNine; const SInt32 kMacOS91 = kMacOSNinePointOne; const SInt32 kMacOSX = kMacOSTen; /* RESOURCES */ enum // menus { kEditorMenu = 128 }; enum // windows { kFileWindow7 = 128, kFileWindow8 = 129 }; enum // controls { kSystem7ScrollBarControl = 128, kAppearanceScrollBarControl = 129, kNormalHeaderControl = 130 }; #endif \ No newline at end of file +#if !TARGET_API_MAC_OS8 #if defined(__APPLE_CC__) // compiling with gcc #include #else // compiling with CodeWarrior, __MWERKS__ #include #endif #endif #ifndef _ResKnife_Plug_ #define _ResKnife_Plug_ 1 #include "HostCallbacks.h" #endif #ifndef _ResKnife_PictEditor_ #define _ResKnife_PictEditor_ // abbreviations #define null NULL #define Use_Nibs 0 #define Use_GWorlds 1 // Easier API call names #define GetWindowRefCon( window ) (long) GetWRefCon( window ) #define SetWindowRefCon( window, refcon ) SetWRefCon( window, refcon ) #define GetWindowTitle( window, string ) GetWTitle( window, string ) #define SetWindowTitle( window, name ) SetWTitle( window, name ) #define InvalidateRect( bounds ) InvalRect( bounds ) #define InvalidateWindowRect( window, bounds ) (OSStatus) InvalWindowRect( window, bounds ) #define RectToRegion( region, rect ) RectRgn( region, rect ) #define SetPoint( point, x, y ) SetPt( point, x, y ) #define HilightColour( colour ) HiliteColor( colour ) #define GetPortHilightColour( window, colour ) GetPortHiliteColor( window, colour ) /* Global Variables */ struct globals { // application Str255 fragName; Str255 prefsName; // system info SInt32 systemVersion; Boolean dragAvailable; Boolean translucentDrag; Boolean navAvailable; Boolean useAppearance; // colours RGBColor white; // 0xFFFF, 65535 RGBColor bgColour; // 0xEEEE, 61166 RGBColor black; // 0x0000, 0 }; /* Preferences */ struct prefs { UInt32 version; // == kPictEditorCurrentVersion, when saved to disk allows older prefs to be read in UInt8 GWorldDepth; }; /*** CONSTANTS ***/ const UInt32 kPictEditorCurrentVersion = 0x00030003; const UInt16 kHeaderHeight = 20; const UInt16 kScrollBarWidth = 16; const UInt16 kMinimumWindowWidth = 384; const UInt16 kDefaultWindowWidth = kMinimumWindowWidth; const UInt16 kMinimumWindowHeight = 256 + kHeaderHeight; const UInt16 kDefaultWindowHeight = kMinimumWindowHeight; const UInt32 kHeaderSignature = FOUR_CHAR_CODE('head'); const UInt32 kLeftTextSignature = FOUR_CHAR_CODE('left'); const UInt32 kRightTextSignature = FOUR_CHAR_CODE('rght'); const UInt32 kScrollbarSignature = FOUR_CHAR_CODE('scrl'); // MacOS versions const SInt32 kMacOSSevenPointOne = 0x00000710; const SInt32 kMacOSSevenPointFivePointFive = 0x00000755; const SInt32 kMacOSEight = 0x00000800; const SInt32 kMacOSEightPointFive = 0x00000850; const SInt32 kMacOSEightPointSix = 0x00000860; const SInt32 kMacOSNine = 0x00000900; const SInt32 kMacOSNinePointOne = 0x00000910; const SInt32 kMacOSTen = 0x00001000; const SInt32 kMacOS71 = kMacOSSevenPointOne; const SInt32 kMacOS755 = kMacOSSevenPointFivePointFive; const SInt32 kMacOS8 = kMacOSEight; const SInt32 kMacOS85 = kMacOSEightPointFive; const SInt32 kMacOS86 = kMacOSEightPointSix; const SInt32 kMacOS9 = kMacOSNine; const SInt32 kMacOS91 = kMacOSNinePointOne; const SInt32 kMacOSX = kMacOSTen; /* RESOURCES */ enum // menus { kEditorMenu = 128 }; enum // windows { kFileWindow7 = 128, kFileWindow8 = 129 }; enum // controls { kSystem7ScrollBarControl = 128, kAppearanceScrollBarControl = 129, kNormalHeaderControl = 130 }; #endif \ No newline at end of file diff --git a/ResKnife.mcp b/ResKnife.mcp index 6f2fbf1..39c35bc 100644 Binary files a/ResKnife.mcp and b/ResKnife.mcp differ diff --git a/ResKnife.pbproj/project.pbxproj b/ResKnife.pbproj/project.pbxproj index 7c1673e..60f02c2 100644 --- a/ResKnife.pbproj/project.pbxproj +++ b/ResKnife.pbproj/project.pbxproj @@ -39,10 +39,10 @@ }; F5354435022673C101A80001 = { children = ( - F535444D0226B5F501A80001, - F535444E0226B5F501A80001, F535443E0226752901A80001, F535443F0226752901A80001, + F535444D0226B5F501A80001, + F535444E0226B5F501A80001, F5D0CBD302278F8B01A80001, F535443D0226752901A80001, ); @@ -80,8 +80,8 @@ productName = "Template Editor Cocoa"; productReference = F5354436022674B301A80001; productSettingsXML = " - - + + CFBundleDevelopmentRegion English @@ -121,6 +121,7 @@ F535444F0226B5F501A80001, ); isa = PBXHeadersBuildPhase; + runOnlyForDeploymentPostprocessing = 0; }; F5354439022674B401A80001 = { buildActionMask = 2147483647; @@ -129,6 +130,7 @@ F5D0CBD402278F8B01A80001, ); isa = PBXResourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; }; F535443A022674B401A80001 = { buildActionMask = 2147483647; @@ -138,6 +140,7 @@ F5C9ECD4027F474A01A8010C, ); isa = PBXSourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; }; F535443B022674B401A80001 = { buildActionMask = 2147483647; @@ -145,12 +148,14 @@ F53544460226907801A80001, ); isa = PBXFrameworksBuildPhase; + runOnlyForDeploymentPostprocessing = 0; }; F535443C022674B401A80001 = { buildActionMask = 2147483647; files = ( ); isa = PBXRezBuildPhase; + runOnlyForDeploymentPostprocessing = 0; }; F535443D0226752901A80001 = { isa = PBXFileReference; @@ -314,18 +319,6 @@ settings = { }; }; - F54627060291788401A8010C = { - isa = PBXTargetDependency; - target = F5B588D20156D78201000001; - }; - F54627070291788801A8010C = { - isa = PBXTargetDependency; - target = F5B588EE0156DAF301000001; - }; - F54627080291788A01A8010C = { - isa = PBXTargetDependency; - target = F5B5890B0156DC2201000001; - }; F546270B02917D1501A8010C = { buildActionMask = 2147483647; files = ( @@ -349,6 +342,7 @@ F546273202917DE801A8010C, ); isa = PBXHeadersBuildPhase; + runOnlyForDeploymentPostprocessing = 0; }; F546270C02917D1501A8010C = { buildActionMask = 2147483647; @@ -370,6 +364,7 @@ F546273302917DE901A8010C, ); isa = PBXSourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; }; F546270D02917D1501A8010C = { buildActionMask = 2147483647; @@ -377,12 +372,14 @@ F546271202917DBB01A8010C, ); isa = PBXFrameworksBuildPhase; + runOnlyForDeploymentPostprocessing = 0; }; F546270E02917D1501A8010C = { buildActionMask = 2147483647; files = ( ); isa = PBXRezBuildPhase; + runOnlyForDeploymentPostprocessing = 0; }; F546270F02917D1501A8010C = { buildPhases = ( @@ -418,10 +415,6 @@ path = libResKnife.dylib; refType = 3; }; - F546271102917D2001A8010C = { - isa = PBXTargetDependency; - target = F546270F02917D1501A8010C; - }; F546271202917DBB01A8010C = { fileRef = F5B5884A0156D40B01000001; isa = PBXBuildFile; @@ -711,6 +704,10 @@ children = ( F5D0CBCF022744C701A80001, F5D0CBD0022744C701A80001, + F59D5DE40320DFF601A8010C, + F59D5DE50320DFF601A8010C, + F59D5DE8032106D201A8010C, + F59D5DE9032106D201A8010C, ); isa = PBXGroup; path = Categories; @@ -852,6 +849,7 @@ F58F6BB0025BE22201A8010C, ); isa = PBXCopyFilesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; }; F57CEE0B0189C95101A8010B = { children = ( @@ -894,8 +892,8 @@ productName = "Hex Editor Cocoa"; productReference = F57CEE0D0189C95101A8010B; productSettingsXML = " - - + + CFBundleDevelopmentRegion English @@ -939,6 +937,7 @@ F54E6224021B6A0901A80001, ); isa = PBXHeadersBuildPhase; + runOnlyForDeploymentPostprocessing = 0; }; F57CEE100189C95101A8010B = { buildActionMask = 2147483647; @@ -949,6 +948,7 @@ F5606FDF02ACF2F701A8010C, ); isa = PBXResourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; }; F57CEE110189C95101A8010B = { buildActionMask = 2147483647; @@ -960,6 +960,7 @@ F5C9ECD2027F474A01A8010C, ); isa = PBXSourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; }; F57CEE120189C95101A8010B = { buildActionMask = 2147483647; @@ -967,12 +968,14 @@ F5502C3301C5586301C57124, ); isa = PBXFrameworksBuildPhase; + runOnlyForDeploymentPostprocessing = 0; }; F57CEE130189C95101A8010B = { buildActionMask = 2147483647; files = ( ); isa = PBXRezBuildPhase; + runOnlyForDeploymentPostprocessing = 0; }; F58A183F0278353501A8010C = { children = ( @@ -1201,6 +1204,56 @@ settings = { }; }; + F591B14F030E9DAA01A8010C = { + fileRef = F5B5884A0156D40B01000001; + isa = PBXBuildFile; + settings = { + }; + }; + F59D5DE40320DFF601A8010C = { + isa = PBXFileReference; + path = "NSString-FSSpec.h"; + refType = 4; + }; + F59D5DE50320DFF601A8010C = { + isa = PBXFileReference; + path = "NSString-FSSpec.m"; + refType = 4; + }; + F59D5DE60320DFF601A8010C = { + fileRef = F59D5DE40320DFF601A8010C; + isa = PBXBuildFile; + settings = { + }; + }; + F59D5DE70320DFF601A8010C = { + fileRef = F59D5DE50320DFF601A8010C; + isa = PBXBuildFile; + settings = { + }; + }; + F59D5DE8032106D201A8010C = { + isa = PBXFileReference; + path = "NSNumber-Range.h"; + refType = 4; + }; + F59D5DE9032106D201A8010C = { + isa = PBXFileReference; + path = "NSNumber-Range.m"; + refType = 4; + }; + F59D5DEA032106D201A8010C = { + fileRef = F59D5DE8032106D201A8010C; + isa = PBXBuildFile; + settings = { + }; + }; + F59D5DEB032106D201A8010C = { + fileRef = F59D5DE9032106D201A8010C; + isa = PBXBuildFile; + settings = { + }; + }; F5B5880F0156D2A601000001 = { buildStyles = ( F5EBF6B801573EC201000001, @@ -1286,8 +1339,8 @@ productName = "ResKnife Cocoa"; productReference = F5B588120156D30301000001; productSettingsXML = " - - + + CFBundleDevelopmentRegion English @@ -1395,8 +1448,10 @@ F5B588590156D40B01000001, F5D0CBD1022744C701A80001, F5DF1BFD0254AD8801A80001, + F59D5DE60320DFF601A8010C, ); isa = PBXHeadersBuildPhase; + runOnlyForDeploymentPostprocessing = 0; }; F5B588150156D30301000001 = { buildActionMask = 2147483647; @@ -1421,6 +1476,7 @@ F577A8F90211DC1E01A80001, ); isa = PBXResourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; }; F5B588160156D30301000001 = { buildActionMask = 2147483647; @@ -1441,8 +1497,10 @@ F5D0CBD2022744C701A80001, F5DF1C070254AD8801A80001, F5C9ECD0027F474A01A8010C, + F59D5DE70320DFF601A8010C, ); isa = PBXSourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; }; F5B588170156D30301000001 = { buildActionMask = 2147483647; @@ -1451,12 +1509,14 @@ F5B588730156D40B01000001, ); isa = PBXFrameworksBuildPhase; + runOnlyForDeploymentPostprocessing = 0; }; F5B588180156D30301000001 = { buildActionMask = 2147483647; files = ( ); isa = PBXRezBuildPhase; + runOnlyForDeploymentPostprocessing = 0; }; F5B5881A0156D40B01000001 = { children = ( @@ -2023,10 +2083,6 @@ WRAPPER_EXTENSION = app; }; dependencies = ( - F546271102917D2001A8010C, - F54627060291788401A8010C, - F54627070291788801A8010C, - F54627080291788A01A8010C, ); isa = PBXApplicationTarget; name = "ResKnife Carbon"; @@ -2034,8 +2090,8 @@ productName = "ResKnife Carbon"; productReference = F5B588740156D5CB01000001; productSettingsXML = " - - + + CFBundleDevelopmentRegion English @@ -2123,6 +2179,7 @@ F5B588B90156D6D901000001, ); isa = PBXHeadersBuildPhase; + runOnlyForDeploymentPostprocessing = 0; }; F5B588770156D5CB01000001 = { buildActionMask = 2147483647; @@ -2130,6 +2187,7 @@ F5B588BC0156D6D901000001, ); isa = PBXResourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; }; F5B588780156D5CB01000001 = { buildActionMask = 2147483647; @@ -2151,6 +2209,7 @@ F5B588CB0156D6D901000001, ); isa = PBXSourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; }; F5B588790156D5CB01000001 = { buildActionMask = 2147483647; @@ -2158,6 +2217,7 @@ F53B5F3201C984F301A8010C, ); isa = PBXFrameworksBuildPhase; + runOnlyForDeploymentPostprocessing = 0; }; F5B5887A0156D5CB01000001 = { buildActionMask = 2147483647; @@ -2166,6 +2226,7 @@ F54627050291767E01A8010C, ); isa = PBXRezBuildPhase; + runOnlyForDeploymentPostprocessing = 0; }; F5B5887C0156D6D901000001 = { children = ( @@ -2659,8 +2720,8 @@ F5B588D70156D78201000001, ); buildSettings = { - LIBRARY_SEARCH_PATHS = /Volumes/DeskStar/nicholas/Projects/ResKnife/Carbon; - OTHER_LDFLAGS = "-bundle -bundle_loader \"$HOME/Projects/ResKnife/build/ResKnife Cocoa.app/Contents/MacOS/ResKnife Cocoa\" -undefined error"; + LIBRARY_SEARCH_PATHS = "\"/Users/nicholas/Projects/ResKnife/Carbon\""; + OTHER_LDFLAGS = "-bundle -bundle_loader \"$HOME/Projects/ResKnife/build/ResKnife Carbon\" -undefined error"; OTHER_REZFLAGS = ""; PRODUCT_NAME = "Hex Editor"; SECTORDER_FLAGS = ""; @@ -2674,8 +2735,8 @@ productName = "Hex Editor"; productReference = F5B588D10156D78201000001; productSettingsXML = " - - + + CFBundleDevelopmentRegion English @@ -2715,12 +2776,14 @@ F535442F0225D46C01A80001, ); isa = PBXHeadersBuildPhase; + runOnlyForDeploymentPostprocessing = 0; }; F5B588D40156D78201000001 = { buildActionMask = 2147483647; files = ( ); isa = PBXResourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; }; F5B588D50156D78201000001 = { buildActionMask = 2147483647; @@ -2731,6 +2794,7 @@ F5B588EB0156D9D401000001, ); isa = PBXSourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; }; F5B588D60156D78201000001 = { buildActionMask = 2147483647; @@ -2739,12 +2803,14 @@ F546273402917E5601A8010C, ); isa = PBXFrameworksBuildPhase; + runOnlyForDeploymentPostprocessing = 0; }; F5B588D70156D78201000001 = { buildActionMask = 2147483647; files = ( ); isa = PBXRezBuildPhase; + runOnlyForDeploymentPostprocessing = 0; }; F5B588D80156D9D401000001 = { children = ( @@ -2807,12 +2873,14 @@ }; F5B588E10156D9D401000001 = { isa = PBXFileReference; - path = Utility.h; + name = Utility.h; + path = HexUtility.h; refType = 4; }; F5B588E20156D9D401000001 = { isa = PBXFileReference; - path = Utility.cpp; + name = Utility.cpp; + path = HexUtility.cpp; refType = 4; }; F5B588E30156D9D401000001 = { @@ -2905,8 +2973,8 @@ productName = "Template Editor"; productReference = F5B588ED0156DAF301000001; productSettingsXML = " - - + + CFBundleDevelopmentRegion English @@ -2939,25 +3007,26 @@ buildActionMask = 2147483647; files = ( F5B589040156DC2201000001, - F5B589050156DC2201000001, F5B589060156DC2201000001, F53544320226550001A80001, ); isa = PBXHeadersBuildPhase; + runOnlyForDeploymentPostprocessing = 0; }; F5B588F00156DAF301000001 = { buildActionMask = 2147483647; files = ( ); isa = PBXResourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; }; F5B588F10156DAF301000001 = { buildActionMask = 2147483647; files = ( - F5B589070156DC2201000001, F5B589080156DC2201000001, ); isa = PBXSourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; }; F5B588F20156DAF301000001 = { buildActionMask = 2147483647; @@ -2965,6 +3034,7 @@ F5B589090156DC2201000001, ); isa = PBXFrameworksBuildPhase; + runOnlyForDeploymentPostprocessing = 0; }; F5B588F30156DAF301000001 = { buildActionMask = 2147483647; @@ -2972,6 +3042,7 @@ F5B5890A0156DC2201000001, ); isa = PBXRezBuildPhase; + runOnlyForDeploymentPostprocessing = 0; }; F5B588F40156DC2201000001 = { children = ( @@ -2990,8 +3061,8 @@ }; F5B588F60156DC2201000001 = { children = ( - F5B588F70156DC2201000001, - F5B588F80156DC2201000001, + F5F98D4502F0B06E01A8010C, + F5F98D4602F0B06E01A8010C, F5B588F90156DC2201000001, F5B588FA0156DC2201000001, ); @@ -2999,16 +3070,6 @@ path = Classes; refType = 4; }; - F5B588F70156DC2201000001 = { - isa = PBXFileReference; - path = Initalisation.h; - refType = 4; - }; - F5B588F80156DC2201000001 = { - isa = PBXFileReference; - path = Initalisation.cpp; - refType = 4; - }; F5B588F90156DC2201000001 = { isa = PBXFileReference; path = TemplateWindow.h; @@ -3080,24 +3141,12 @@ settings = { }; }; - F5B589050156DC2201000001 = { - fileRef = F5B588F70156DC2201000001; - isa = PBXBuildFile; - settings = { - }; - }; F5B589060156DC2201000001 = { fileRef = F5B588F90156DC2201000001; isa = PBXBuildFile; settings = { }; }; - F5B589070156DC2201000001 = { - fileRef = F5B588F80156DC2201000001; - isa = PBXBuildFile; - settings = { - }; - }; F5B589080156DC2201000001 = { fileRef = F5B588FA0156DC2201000001; isa = PBXBuildFile; @@ -3141,8 +3190,8 @@ productName = "PICT Editor"; productReference = F5B589030156DC2201000001; productSettingsXML = " - - + + CFBundleDevelopmentRegion English @@ -3179,6 +3228,7 @@ F5B5890F0156DC2201000001, ); isa = PBXHeadersBuildPhase; + runOnlyForDeploymentPostprocessing = 0; }; F5B5890D0156DC2201000001 = { fileRef = F5B588FF0156DC2201000001; @@ -3203,6 +3253,7 @@ files = ( ); isa = PBXResourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; }; F5B589110156DC2201000001 = { buildActionMask = 2147483647; @@ -3211,6 +3262,7 @@ F5B589130156DC2201000001, ); isa = PBXSourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; }; F5B589120156DC2201000001 = { fileRef = F5B589000156DC2201000001; @@ -3230,6 +3282,7 @@ F5B589150156DC2201000001, ); isa = PBXFrameworksBuildPhase; + runOnlyForDeploymentPostprocessing = 0; }; F5B589150156DC2201000001 = { fileRef = F5B5884A0156D40B01000001; @@ -3242,6 +3295,7 @@ files = ( ); isa = PBXRezBuildPhase; + runOnlyForDeploymentPostprocessing = 0; }; F5C9ECCE027F474A01A8010C = { isa = PBXFileReference; @@ -3534,8 +3588,8 @@ productName = "NovaToolsâ„¢"; productReference = F5DF1C080254C6BA01A80001; productSettingsXML = " - - + + CFBundleDevelopmentRegion English @@ -3583,8 +3637,10 @@ F58A18430278355D01A8010C, F543AFDD027B2A5001A8010C, F5C9ECD9027F562201A8010C, + F59D5DEA032106D201A8010C, ); isa = PBXHeadersBuildPhase; + runOnlyForDeploymentPostprocessing = 0; }; F5DF1C0B0254C6BA01A80001 = { buildActionMask = 2147483647; @@ -3598,6 +3654,7 @@ F543AFF1027C716E01A8010C, ); isa = PBXResourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; }; F5DF1C0C0254C6BA01A80001 = { buildActionMask = 2147483647; @@ -3611,21 +3668,26 @@ F58A18420278355D01A8010C, F543AFDE027B2A5001A8010C, F5C9ECD6027F474A01A8010C, + F59D5DEB032106D201A8010C, ); isa = PBXSourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; }; F5DF1C0D0254C6BA01A80001 = { buildActionMask = 2147483647; files = ( F58F6BAE025BE1E001A8010C, + F591B14F030E9DAA01A8010C, ); isa = PBXFrameworksBuildPhase; + runOnlyForDeploymentPostprocessing = 0; }; F5DF1C0E0254C6BA01A80001 = { buildActionMask = 2147483647; files = ( ); isa = PBXRezBuildPhase; + runOnlyForDeploymentPostprocessing = 0; }; F5DF1C0F0254C78801A80001 = { children = ( @@ -3904,6 +3966,16 @@ settings = { }; }; + F5F98D4502F0B06E01A8010C = { + isa = PBXFileReference; + path = TemplateInitalisation.h; + refType = 4; + }; + F5F98D4602F0B06E01A8010C = { + isa = PBXFileReference; + path = TemplateInitalisation.cpp; + refType = 4; + }; }; rootObject = F5B5880F0156D2A601000001; } diff --git a/Template Editor/Template Editor.h b/Template Editor/Template Editor.h index bb23602..9f10cb2 100644 --- a/Template Editor/Template Editor.h +++ b/Template Editor/Template Editor.h @@ -1 +1 @@ -#if !TARGET_API_MAC_OS8 #include #endif #ifndef _ResKnife_Plug_ #define _ResKnife_Plug_ 1 #include "HostCallbacks.h" #endif #ifndef _ResKnife_TemplateEditor_ #define _ResKnife_TemplateEditor_ #include "Generic.h" // abbreviations #define Use_Nibs 0 #define Use_GWorlds 1 /* Global Variables */ struct globals { // application Str255 fragName; Str255 prefsName; // system info SInt32 systemVersion; Boolean dragAvailable; Boolean translucentDrag; Boolean navAvailable; Boolean useAppearance; // colours RGBColor white; // 0xFFFF, 65535 RGBColor bgColour; // 0xEEEE, 61166 RGBColor black; // 0x0000, 0 }; /* Preferences */ struct prefs { UInt32 version; // == kTemplateEditorCurrentVersion, when saved to disk allows older prefs to be read in UInt8 GWorldDepth; }; /*** CONSTANTS ***/ const UInt32 kTemplateEditorCurrentVersion = 0x00030003; const UInt16 kHeaderHeight = 20; const UInt16 kScrollBarWidth = 16; const UInt16 kMinimumWindowWidth = 384; const UInt16 kDefaultWindowWidth = kMinimumWindowWidth; const UInt16 kMinimumWindowHeight = 256 + kHeaderHeight; const UInt16 kDefaultWindowHeight = kMinimumWindowHeight; // MacOS versions const SInt32 kMacOSSevenPointOne = 0x00000710; const SInt32 kMacOSSevenPointFivePointFive = 0x00000755; const SInt32 kMacOSEight = 0x00000800; const SInt32 kMacOSEightPointFive = 0x00000850; const SInt32 kMacOSEightPointSix = 0x00000860; const SInt32 kMacOSNine = 0x00000900; const SInt32 kMacOSNinePointOne = 0x00000910; const SInt32 kMacOSTen = 0x00001000; const SInt32 kMacOS71 = kMacOSSevenPointOne; const SInt32 kMacOS755 = kMacOSSevenPointFivePointFive; const SInt32 kMacOS8 = kMacOSEight; const SInt32 kMacOS85 = kMacOSEightPointFive; const SInt32 kMacOS86 = kMacOSEightPointSix; const SInt32 kMacOS9 = kMacOSNine; const SInt32 kMacOS91 = kMacOSNinePointOne; const SInt32 kMacOSX = kMacOSTen; /* RESOURCES */ enum // menus { kEditorMenu = 128 }; enum // windows { kFileWindow7 = 128, kFileWindow8 = 129 }; enum // controls { kSystem7ScrollBarControl = 128, kAppearanceScrollBarControl = 129, kNormalHeaderControl = 130 }; #endif \ No newline at end of file +#if !TARGET_API_MAC_OS8 #if defined(__APPLE_CC__) // compiling with gcc #include #else // compiling with CodeWarrior, __MWERKS__ #include #endif #endif #ifndef _ResKnife_Plug_ #define _ResKnife_Plug_ 1 #include "HostCallbacks.h" #endif #ifndef _ResKnife_TemplateEditor_ #define _ResKnife_TemplateEditor_ #include "Generic.h" // abbreviations #define Use_Nibs 0 #define Use_GWorlds 1 /* Global Variables */ struct globals { // application Str255 fragName; Str255 prefsName; // system info SInt32 systemVersion; Boolean dragAvailable; Boolean translucentDrag; Boolean navAvailable; Boolean useAppearance; // colours RGBColor white; // 0xFFFF, 65535 RGBColor bgColour; // 0xEEEE, 61166 RGBColor black; // 0x0000, 0 }; /* Preferences */ struct prefs { UInt32 version; // == kTemplateEditorCurrentVersion, when saved to disk allows older prefs to be read in UInt8 GWorldDepth; }; /*** CONSTANTS ***/ const UInt32 kTemplateEditorCurrentVersion = 0x00030003; const UInt16 kHeaderHeight = 20; const UInt16 kScrollBarWidth = 16; const UInt16 kMinimumWindowWidth = 384; const UInt16 kDefaultWindowWidth = kMinimumWindowWidth; const UInt16 kMinimumWindowHeight = 256 + kHeaderHeight; const UInt16 kDefaultWindowHeight = kMinimumWindowHeight; // MacOS versions const SInt32 kMacOSSevenPointOne = 0x00000710; const SInt32 kMacOSSevenPointFivePointFive = 0x00000755; const SInt32 kMacOSEight = 0x00000800; const SInt32 kMacOSEightPointFive = 0x00000850; const SInt32 kMacOSEightPointSix = 0x00000860; const SInt32 kMacOSNine = 0x00000900; const SInt32 kMacOSNinePointOne = 0x00000910; const SInt32 kMacOSTen = 0x00001000; const SInt32 kMacOS71 = kMacOSSevenPointOne; const SInt32 kMacOS755 = kMacOSSevenPointFivePointFive; const SInt32 kMacOS8 = kMacOSEight; const SInt32 kMacOS85 = kMacOSEightPointFive; const SInt32 kMacOS86 = kMacOSEightPointSix; const SInt32 kMacOS9 = kMacOSNine; const SInt32 kMacOS91 = kMacOSNinePointOne; const SInt32 kMacOSX = kMacOSTen; /* RESOURCES */ enum // menus { kEditorMenu = 128 }; enum // windows { kFileWindow7 = 128, kFileWindow8 = 129 }; enum // controls { kSystem7ScrollBarControl = 128, kAppearanceScrollBarControl = 129, kNormalHeaderControl = 130 }; #endif \ No newline at end of file diff --git a/Template Editor/Template Editor.r b/Template Editor/Template Editor.r index db0231d..3914d24 100644 --- a/Template Editor/Template Editor.r +++ b/Template Editor/Template Editor.r @@ -1,7 +1,7 @@ -#ifdef __MWERKS__ - #include -#else +#if defined(__APPLE_CC__) // compiling with gcc #include +#else // compiling with CodeWarrior, __MWERKS__ + #include #endif /*** FILE MENU ***/