From 9c92717c15e834fa162ea1f496f95cd1265fe052 Mon Sep 17 00:00:00 2001 From: Jeff Teunissen Date: Wed, 21 Nov 2001 18:47:08 +0000 Subject: [PATCH] The beginnings of bundle-loading support Scary, but it seems to work! --- tools/Forge/BundleController.h | 68 +++++++ tools/Forge/BundleController.m | 170 ++++++++++++++++++ tools/Forge/Bundles/MainPrefs/.gitignore | 7 + tools/Forge/Bundles/MainPrefs/GNUmakefile | 20 +++ .../Bundles/MainPrefs/GNUmakefile.preamble | 39 ++++ tools/Forge/Bundles/MainPrefs/MainPrefsView.h | 37 ++++ tools/Forge/Bundles/MainPrefs/MainPrefsView.m | 46 +++++ tools/Forge/Controller.m | 26 +-- tools/Forge/English.lproj/Localizable.strings | 4 + tools/Forge/Forge.classes | 16 +- tools/Forge/Forge.gorm | Bin 10202 -> 10318 bytes tools/Forge/GNUmakefile | 5 + tools/Forge/PrefsController.h | 11 +- tools/Forge/PrefsController.m | 89 ++++++--- tools/Forge/PrefsPanel.h | 3 +- tools/Forge/PrefsPanel.m | 31 ++-- tools/Forge/PrefsView.h | 18 +- tools/Forge/main.m | 1 - 18 files changed, 516 insertions(+), 75 deletions(-) create mode 100644 tools/Forge/BundleController.h create mode 100644 tools/Forge/BundleController.m create mode 100644 tools/Forge/Bundles/MainPrefs/.gitignore create mode 100644 tools/Forge/Bundles/MainPrefs/GNUmakefile create mode 100644 tools/Forge/Bundles/MainPrefs/GNUmakefile.preamble create mode 100644 tools/Forge/Bundles/MainPrefs/MainPrefsView.h create mode 100644 tools/Forge/Bundles/MainPrefs/MainPrefsView.m diff --git a/tools/Forge/BundleController.h b/tools/Forge/BundleController.h new file mode 100644 index 000000000..60fd0dbb4 --- /dev/null +++ b/tools/Forge/BundleController.h @@ -0,0 +1,68 @@ +/* + BundleController.h + + Bundle manager class and protocol + + Copyright (C) 2001 Dusk to Dawn Computing, Inc. + Additional copyrights here + + Author: Jeff Teunissen + Date: 20 Nov 2001 + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public + License along with this program; if not, write to: + + Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA +*/ + +#ifdef HAVE_CONFIG_H +# include "Config.h" +#endif + +#import +#import +#import + +/* + Bundle Delegate protocol + + App controllers need to adopt this protocol to receive notifications +*/ +@class BundleController; // forward reference so the compiler doesn't get confused +@protocol BundleDelegate + +// Notification, sent when a bundle is loaded. +- (void) bundleController: (BundleController *) aController didLoadBundle: (NSBundle *) aBundle; + +@end + +@interface BundleController: NSObject +{ + id delegate; + NSMutableArray *loadedBundles; +} + +- (id) init; +- (void) dealloc; + +- (id) delegate; +- (void) setDelegate: (id) aDelegate; + +- (void) loadBundles; + +- (NSArray *) loadedBundles; + +@end diff --git a/tools/Forge/BundleController.m b/tools/Forge/BundleController.m new file mode 100644 index 000000000..760a28835 --- /dev/null +++ b/tools/Forge/BundleController.m @@ -0,0 +1,170 @@ +/* + BundleController.m + + Bundle manager class + + Copyright (C) 2001 Dusk to Dawn Computing, Inc. + Additional copyrights here + + Author: Jeff Teunissen + Date: 20 Nov 2001 + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public + License along with this program; if not, write to: + + Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA +*/ +static const char rcsid[] = + "$Id$"; + +#ifdef HAVE_CONFIG_H +# include "Config.h" +#endif + +#import +#import +#import +#import "BundleController.h" + +@interface BundleController (Private) + +- (void) loadBundleInPath: (NSString *) path; +- (NSArray *) bundlesWithExtension: (NSString *) extension inPath: (NSString *) path; + +@end + +@implementation BundleController (Private) + +- (void) loadBundleInPath: (NSString *) path +{ + NSBundle *bundle; + + if (!path) { + NSLog (@"%@ -loadBundleInPath: No path given!", [[self class] description]); + return; + } + + NSDebugLog (@"Loading bundle %@...", path); + + if ((bundle = [NSBundle bundleWithPath: path])) { + NSDebugLog (@"Bundle %@ successfully loaded.", path); + + /* + Fire off the notification if we have a delegate that adopts the + BundleDelegate protocol + */ + if (delegate && [delegate conformsToProtocol: @protocol(BundleDelegate)]) + [(id ) delegate bundleController: self didLoadBundle: bundle]; + [self bundleController: self didLoadBundle: bundle]; + } else { + NSRunAlertPanel (@"Attention", @"Could not load bundle %@", @"OK", nil, nil, path); + } +} + +- (NSArray *) bundlesWithExtension: (NSString *) extension inPath: (NSString *) path +{ + NSMutableArray *bundleList = [[NSMutableArray alloc] initWithCapacity: 10]; + NSEnumerator *enumerator; + NSFileManager *fm = [NSFileManager defaultManager]; + NSString *dir; + BOOL isDir; + + // ensure path exists, and is a directory + if (![fm fileExistsAtPath: path isDirectory: &isDir]) + return; + + if (!isDir) + return; + + // scan for bundles matching the extension in the dir + enumerator = [[fm directoryContentsAtPath: path] objectEnumerator]; + while ((dir = [enumerator nextObject])) { + if ([[dir pathExtension] isEqualToString: extension]) + [bundleList addObject: dir]; + } +} + +@end + +@implementation BundleController + +- (id) init +{ + if ((self = [super init])) + loadedBundles = [[NSMutableArray alloc] init]; + return self; +} + +- (void) dealloc +{ + [loadedBundles release]; + + [super dealloc]; +} + +- (id) delegate +{ + return delegate; +} + +- (void) setDelegate: (id) aDelegate; +{ + delegate = aDelegate; +} + +- (void) loadBundles +{ + NSMutableArray *dirList = [[NSMutableArray alloc] initWithCapacity: 10]; + NSArray *temp; + NSMutableArray *modified = [[NSMutableArray alloc] initWithCapacity: 10]; + NSEnumerator *counter; + id obj; + + // Start out with our own resource dir + [dirList addObject: [[NSBundle mainBundle] resourcePath]]; + + // Get the library dirs and add our path to all of its entries + temp = NSSearchPathForDirectoriesInDomains (NSLibraryDirectory, NSAllDomainsMask, YES); + + counter = [temp objectEnumerator]; + while ((obj = [counter nextObject])) { + [modified addObject: [obj stringByAppendingPathComponent: @"Forge"]]; + } + [dirList addObjectsFromArray: modified]; + + // Okay, now go through dirList loading all of the bundles in each dir + counter = [dirList objectEnumerator]; + while ((obj = [counter nextObject])) { + NSEnumerator *enum2 = [[self bundlesWithExtension: @"Forge" inPath: obj] objectEnumerator]; + NSString *str; + + while ((str = [enum2 nextObject])) { + [self loadBundleInPath: str]; + } + } +} + +- (NSArray *) loadedBundles +{ + return loadedBundles; +} + +- (void) bundleController: (BundleController *) aController didLoadBundle: (NSBundle *) aBundle +{ + [loadedBundles addObject: aBundle]; +} + +@end diff --git a/tools/Forge/Bundles/MainPrefs/.gitignore b/tools/Forge/Bundles/MainPrefs/.gitignore new file mode 100644 index 000000000..1e6ad49c6 --- /dev/null +++ b/tools/Forge/Bundles/MainPrefs/.gitignore @@ -0,0 +1,7 @@ +.vimrc +shared_debug_obj +shared_obj +shared_profile_debug_obj +shared_profile_obj +obj +*.forgeb diff --git a/tools/Forge/Bundles/MainPrefs/GNUmakefile b/tools/Forge/Bundles/MainPrefs/GNUmakefile new file mode 100644 index 000000000..7eae8ce24 --- /dev/null +++ b/tools/Forge/Bundles/MainPrefs/GNUmakefile @@ -0,0 +1,20 @@ +include $(GNUSTEP_MAKEFILES)/common.make + +BUNDLE_NAME= MainPrefs +BUNDLE_EXTENSION= .forgeb +BUNDLE_INSTALL_DIR= $(GNUSTEP_LOCAL_ROOT)/Library/Forge + +MainPrefs_OBJC_FILES= \ + MainPrefsView.m + +MainPrefs_HEADERS= \ + MainPrefsView.h + +MainPrefs_PRINCIPAL_CLASS= \ + MainPrefsController + +-include GNUmakefile.preamble + +include $(GNUSTEP_MAKEFILES)/bundle.make + +-include GNUmakefile.postamble diff --git a/tools/Forge/Bundles/MainPrefs/GNUmakefile.preamble b/tools/Forge/Bundles/MainPrefs/GNUmakefile.preamble new file mode 100644 index 000000000..8c5340059 --- /dev/null +++ b/tools/Forge/Bundles/MainPrefs/GNUmakefile.preamble @@ -0,0 +1,39 @@ +# Additional flags to pass to the preprocessor +ADDITIONAL_CPPFLAGS += + +# Additional flags to pass to the Objective-C compiler +ADDITIONAL_OBJCFLAGS += + +# Additional flags to pass to the C compiler +ADDITIONAL_CFLAGS += + +# Additional include directories the compiler should search +ADDITIONAL_INCLUDE_DIRS += -I ../.. + +# Additional LDFLAGS to pass to the linker +ADDITIONAL_LDFLAGS += + +# Additional library directories the linker should search +ADDITIONAL_LIB_DIRS += + +# Additional libraries + +# GNUstepWeb +ADDITIONAL_GSW_LIBS += +# GUI apps +ADDITIONAL_GUI_LIBS += +# Libraries +ADDITIONAL_LIBRARY_LIBS += +# ObjC stuff +ADDITIONAL_OBJC_LIBS += +# Tools +ADDITIONAL_TOOL_LIBS += +# WebObjects +ADDITIONAL_WO_LIBS += + +# +# Flags dealing with installing and uninstalling +# + +# Additional directories to be created during installation +ADDITIONAL_INSTALL_DIRS += diff --git a/tools/Forge/Bundles/MainPrefs/MainPrefsView.h b/tools/Forge/Bundles/MainPrefs/MainPrefsView.h new file mode 100644 index 000000000..67d2cf4a9 --- /dev/null +++ b/tools/Forge/Bundles/MainPrefs/MainPrefsView.h @@ -0,0 +1,37 @@ +/* + ForgePrefsView.h + + Forge internal preferences view + + Copyright (C) 2001 Dusk to Dawn Computing, Inc. + + Author: Jeff Teunissen + Date: 17 Nov 2001 + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public + License along with this program; if not, write to: + + Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA +*/ + +#ifdef HAVE_CONFIG_H +# include "Config.h" +#endif + +#import "PrefsView.h" + +@interface MainPrefsView: NSView +@end diff --git a/tools/Forge/Bundles/MainPrefs/MainPrefsView.m b/tools/Forge/Bundles/MainPrefs/MainPrefsView.m new file mode 100644 index 000000000..ac6b2778d --- /dev/null +++ b/tools/Forge/Bundles/MainPrefs/MainPrefsView.m @@ -0,0 +1,46 @@ +/* + MainPrefsView.m + + Forge internal preferences view + + Copyright (C) 2001 Dusk to Dawn Computing, Inc. + + Author: Jeff Teunissen + Date: 17 Nov 2001 + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public + License along with this program; if not, write to: + + Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA +*/ +static const char rcsid[] = + "$Id$"; + +#ifdef HAVE_CONFIG_H +# include "Config.h" +#endif + +#import +#import + +#import "MainPrefsView.h" + +@implementation MainPrefsView + +- (void) initUI +{ +} +@end diff --git a/tools/Forge/Controller.m b/tools/Forge/Controller.m index f1f303568..9a0c116c2 100644 --- a/tools/Forge/Controller.m +++ b/tools/Forge/Controller.m @@ -109,13 +109,7 @@ static PrefsController *prefsController = nil; - (void) showPreferencesPanel: (id) sender; { NSDebugLog (@"Showing Preferences panel..."); - - if (!prefsController) - prefsController = [[PrefsController alloc] init]; - - [prefsController orderFrontPreferencesPanel: self]; - - return; + [[PrefsController sharedPrefsController] orderFrontPreferencesPanel: self]; } /* @@ -152,8 +146,6 @@ static PrefsController *prefsController = nil; [menu addItemWithTitle: _(@"Project") action: NULL keyEquivalent: @""]; [menu addItemWithTitle: _(@"File") action: NULL keyEquivalent: @""]; [menu addItemWithTitle: _(@"Edit") action: NULL keyEquivalent: @""]; - [menu addItemWithTitle: _(@"BSP") action: NULL keyEquivalent: @""]; - [menu addItemWithTitle: _(@"Brush") action: NULL keyEquivalent: @""]; [menu addItemWithTitle: _(@"Windows") action: NULL keyEquivalent: @""]; [menu addItemWithTitle: _(@"Services") action: NULL keyEquivalent: @""]; @@ -254,22 +246,6 @@ static PrefsController *prefsController = nil; action: @selector (selectAll:) keyEquivalent: @"a"]; - /* - BSP - */ - bsp = [[[NSMenu alloc] init] autorelease]; - [menu setSubmenu: bsp forItem: [menu itemWithTitle: _(@"BSP")]]; - - [bsp addItemWithTitle: _(@"None") action: @selector(nothing:) keyEquivalent: @""]; - - /* - Brush - */ - brush = [[[NSMenu alloc] init] autorelease]; - [menu setSubmenu: brush forItem: [menu itemWithTitle: _(@"Brush")]]; - - [brush addItemWithTitle: _(@"None") action: @selector(nothing:) keyEquivalent: @""]; - /* Windows */ diff --git a/tools/Forge/English.lproj/Localizable.strings b/tools/Forge/English.lproj/Localizable.strings index 57c5f9b6a..d1eebf86b 100644 --- a/tools/Forge/English.lproj/Localizable.strings +++ b/tools/Forge/English.lproj/Localizable.strings @@ -1,3 +1,6 @@ +/* App Name */ +"Forge" = "Forge"; + /* Controller.m Menus */ "Info" = "Info"; "Info Panel..." = "Info Panel..."; @@ -42,3 +45,4 @@ "OK" = "OK"; "Cancel" = "Cancel"; "Apply" = "Apply"; +"Default" = "Default"; diff --git a/tools/Forge/Forge.classes b/tools/Forge/Forge.classes index f3a2dc27b..3170b81d0 100644 --- a/tools/Forge/Forge.classes +++ b/tools/Forge/Forge.classes @@ -1,4 +1,13 @@ { + BundleController = { + Actions = ( + setDelegate: + ); + Outlets = ( + delegate + ); + Super = NSObject; + }; Controller = { Actions = ( createNew:, @@ -77,13 +86,6 @@ ); Super = NSResponder; }; - NewClass = { - Actions = ( - ); - Outlets = ( - ); - Super = NSObject; - }; Preferences = { Actions = ( ok:, diff --git a/tools/Forge/Forge.gorm b/tools/Forge/Forge.gorm index 305da3d4c75380cb8577d17a2594227285f82dab..5f8ddc1bc7d4f98937b463c0a5b5926a23b0e29a 100644 GIT binary patch literal 10318 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 +#import "PrefsView.h" + @interface PrefsController: NSWindowController { - NSMutableArray *prefsViews; } ++ (PrefsController *) sharedPrefsController; - (id) init; - (void) dealloc; @@ -50,9 +52,12 @@ Stuff we do in our subclass ***/ - (void) orderFrontPreferencesPanel: (id) sender; -- (void) addPrefsView: (id) aPrefsView; +- (void) addPrefsViewController: (id ) aPrefsViewController; - (void) savePreferences: (id) sender; - (void) savePreferencesAndCloseWindow: (id) sender; +- (void) loadPreferences: (id) sender; +- (void) resetToDefaults: (id) sender; + @end diff --git a/tools/Forge/PrefsController.m b/tools/Forge/PrefsController.m index d385117d3..90dd04ba4 100644 --- a/tools/Forge/PrefsController.m +++ b/tools/Forge/PrefsController.m @@ -37,31 +37,46 @@ static const char rcsid[] = #import "PrefsController.h" #import "PrefsPanel.h" +#import "PrefsView.h" @implementation PrefsController +static PrefsController *sharedInstance = nil; +static NSMutableArray *prefsViews = nil; + ++ (PrefsController *) sharedPrefsController +{ + return (sharedInstance ? sharedInstance : [[self alloc] init]); +} + - (id) init { PrefsPanel *prefsPanel; - prefsViews = [[NSMutableArray alloc] initWithCapacity: 5]; - - prefsPanel = [[PrefsPanel alloc] - initWithContentRect: NSMakeRect (250, 250, 516, 386) - styleMask: NSTitledWindowMask - | NSMiniaturizableWindowMask - | NSClosableWindowMask - backing: NSBackingStoreRetained - defer: NO - ]; - [prefsPanel setTitle: _(@"Preferences")]; + if (sharedInstance) { + [self dealloc]; + } else { + [super init]; + sharedInstance = self; - [super initWithWindow: prefsPanel]; - [prefsPanel initUI]; - [prefsPanel setDelegate: self]; - [prefsPanel release]; + prefsViews = [[[NSMutableArray alloc] initWithCapacity: 5] retain]; - return self; + prefsPanel = [[PrefsPanel alloc] + initWithContentRect: NSMakeRect (250, 250, 516, 386) + styleMask: NSTitledWindowMask + | NSMiniaturizableWindowMask + | NSClosableWindowMask + backing: NSBackingStoreRetained + defer: NO + ]; + [prefsPanel setTitle: [NSString stringWithFormat: @"%@ %@", _(@"Forge"), _(@"Preferences")]]; + + [super initWithWindow: prefsPanel]; + [prefsPanel initUI]; + [prefsPanel setDelegate: self]; + [prefsPanel release]; + } + return sharedInstance; } - (void) dealloc @@ -90,8 +105,8 @@ static const char rcsid[] = - (void) savePreferences: (id) sender { - NSEnumerator *enumerator = [prefsViews objectEnumerator]; - id current; + NSEnumerator *enumerator = [prefsViews objectEnumerator]; + id current; NSDebugLog (@"Saving all preferences..."); while ((current = [enumerator nextObject])) { @@ -101,19 +116,45 @@ static const char rcsid[] = [[NSUserDefaults standardUserDefaults] synchronize]; } -- (void) addPrefsView: (id) aPrefsView; +- (void) loadPreferences: (id) sender +{ + NSEnumerator *enumerator = [prefsViews objectEnumerator]; + id current; + + NSDebugLog (@"Loading all preferences from database..."); + while ((current = [enumerator nextObject])) { + [current loadPrefs: self]; + } + + [[NSUserDefaults standardUserDefaults] synchronize]; +} + +- (void) resetToDefaults: (id) sender +{ + NSEnumerator *enumerator = [prefsViews objectEnumerator]; + id current; + + NSDebugLog (@"Setting all preferences to default values..."); + while ((current = [enumerator nextObject])) { + [current resetPrefsToDefault: self]; + } + + [[NSUserDefaults standardUserDefaults] synchronize]; +} + +- (void) addPrefsViewController: (id ) controller; { PrefsPanel *prefsPanel; prefsPanel = (PrefsPanel *) [self window]; - if (! [prefsViews containsObject: aPrefsView]) { - [prefsViews addObject: aPrefsView]; - [aPrefsView autorelease]; + if (! [prefsViews containsObject: controller]) { + [prefsViews addObject: controller]; + [controller autorelease]; } - [[prefsPanel prefsViewBox] setContentView: aPrefsView]; - [[prefsPanel prefsViewBox] display]; + [[prefsPanel prefsViewBox] setContentView: [controller view]]; + [[prefsPanel prefsViewBox] setNeedsDisplay: YES]; } @end diff --git a/tools/Forge/PrefsPanel.h b/tools/Forge/PrefsPanel.h index 8169cacc1..a17861a7d 100644 --- a/tools/Forge/PrefsPanel.h +++ b/tools/Forge/PrefsPanel.h @@ -47,8 +47,7 @@ - (void) initUI; - (void) dealloc; - -- (void) addPrefsViewButtonWithDescription: (NSString *) desc andImage: (NSImage *) img; +- (void) addPrefsViewButtonWithTitle: (NSString *) desc andImage: (NSImage *) img; - (NSBox *) prefsViewBox; - (NSMatrix *) prefsViewList; diff --git a/tools/Forge/PrefsPanel.m b/tools/Forge/PrefsPanel.m index e4d9ef0f3..7859a7354 100644 --- a/tools/Forge/PrefsPanel.m +++ b/tools/Forge/PrefsPanel.m @@ -34,6 +34,7 @@ static const char rcsid[] = # include "Config.h" #endif +#import #import #import #import @@ -46,7 +47,7 @@ static const char rcsid[] = - (void) initUI { - NSButton *ok, *apply, *cancel; + NSButton *ok, *apply, *cancel, *revert; NSButtonCell *prototype; NSScrollView *iconScrollView; @@ -60,10 +61,11 @@ static const char rcsid[] = Scroll area is 86 pixels tall, 500 wide content view size: (520, 414) */ - + prefsViewBox = [[NSBox alloc] initWithFrame: NSMakeRect (8, 40, 500, 242)]; [prefsViewBox setTitlePosition: NSNoTitle]; [prefsViewBox setBorderType: NSGrooveBorder]; + NSDebugLog (@"prefsViewBox bounds: %@", NSStringFromRect ([[prefsViewBox contentView] bounds])); [[self contentView] addSubview: prefsViewBox]; @@ -87,10 +89,10 @@ static const char rcsid[] = [iconScrollView setHasVerticalScroller: NO]; [iconScrollView setDocumentView: prefsViewList]; [[self contentView] addSubview: iconScrollView]; - + /* Create the buttons */ // OK - ok = [[NSButton alloc] initWithFrame: NSMakeRect (312, 8, 60, 24)]; + ok = [[NSButton alloc] initWithFrame: NSMakeRect (244, 8, 60, 24)]; [ok autorelease]; [ok setTitle: _(@"OK")]; @@ -98,8 +100,8 @@ static const char rcsid[] = [ok setAction: @selector(savePreferencesAndCloseWindow:)]; [[self contentView] addSubview: ok]; - // cancel - cancel = [[NSButton alloc] initWithFrame: NSMakeRect (380, 8, 60, 24)]; + // Cancel + cancel = [[NSButton alloc] initWithFrame: NSMakeRect (312, 8, 60, 24)]; [cancel autorelease]; [cancel setTitle: _(@"Cancel")]; @@ -107,25 +109,34 @@ static const char rcsid[] = [cancel setAction: @selector(close)]; [[self contentView] addSubview: cancel]; - // apply - apply = [[NSButton alloc] initWithFrame: NSMakeRect (448, 8, 60, 24)]; + // Apply + apply = [[NSButton alloc] initWithFrame: NSMakeRect (380, 8, 60, 24)]; [apply autorelease]; [apply setTitle: _(@"Apply")]; [apply setTarget: [self windowController]]; [apply setAction: @selector(savePreferences:)]; [[self contentView] addSubview: apply]; + + // Defaults + revert = [[NSButton alloc] initWithFrame: NSMakeRect (448, 8, 60, 24)]; + [revert autorelease]; + + [revert setTitle: _(@"Default")]; + [revert setTarget: [self windowController]]; + [revert setAction: @selector(resetToDefaults:)]; + [[self contentView] addSubview: revert]; } - (void) dealloc { - NSDebugLog (@"PrefsWindow -dealloc"); + NSDebugLog (@"PrefsPanel -dealloc"); [prefsViewBox release]; [super dealloc]; } -- (void) addPrefsViewButtonWithDescription: (NSString *) desc andImage: (NSImage *) img +- (void) addPrefsViewButtonWithTitle: (NSString *) desc andImage: (NSImage *) img { NSButtonCell *button = [[NSButtonCell alloc] init]; diff --git a/tools/Forge/PrefsView.h b/tools/Forge/PrefsView.h index f5bf8423b..c141cd672 100644 --- a/tools/Forge/PrefsView.h +++ b/tools/Forge/PrefsView.h @@ -33,6 +33,18 @@ #import -@interface PrefsView: NSView -{ -} +// size of a PrefsView +#define PrefsRect NSMakeRect (0, 0, 486, 228) + +@protocol PrefsViewController + +- (void) savePrefs: (id) sender; +- (void) loadPrefs: (id) sender; +- (void) resetPrefsToDefault: (id) sender; + +- (NSView *) view; + +@end + +@interface PrefsViewController +@end diff --git a/tools/Forge/main.m b/tools/Forge/main.m index f965f9bb0..27f6a861f 100644 --- a/tools/Forge/main.m +++ b/tools/Forge/main.m @@ -1,5 +1,4 @@ #import -#import "Controller.h" #define APP_NAME @"Forge"