home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1995 August / NEBULA.mdf / SourceCode / MiscKit1.2.6 / Source / MiscNibController.m < prev    next >
Encoding:
Text File  |  1994-03-16  |  7.0 KB  |  280 lines

  1. //
  2. //    MiscNibController.m -- an abstract superclass to load .nib files with
  3. //            windows in them
  4. //        Written by Mike Ferris (c) 1994 by Mike Ferris.
  5. //        Modified from original MOKit "MOController" class by Don Yacktman.
  6. //                Version 1.0.  All rights reserved.
  7. //
  8. //        This notice may not be removed from this source code.
  9. //
  10. //    This object is included in the MiscKit by permission from the author
  11. //    and its use is governed by the MiscKit license, found in the file
  12. //    "LICENSE.rtf" in the MiscKit distribution.  Please refer to that file
  13. //    for a list of all applicable permissions and restrictions.
  14. //    
  15.  
  16.  
  17. #define MISC_STRING_CLASS_NAME            "MiscString"
  18. #define MISC_CLASSVARIABLE_CLASS_NAME    "MiscClassVariable"
  19.  
  20. #define CLASS_VERSION    0
  21. #define CLASS_NAME        "MiscNibController"
  22.  
  23. #import <misckit/misckit.h>
  24. //#import <misckit/MiscString.h>
  25. //#import <misckit/MiscClassVariable.h>
  26. //#import <misckit/MiscBundleLoader.h>
  27. #import <objc/objc-runtime.h>
  28.  
  29. @implementation MiscNibController
  30.  
  31. // True class variable object
  32. static MiscClassVariable *_MiscClassNibName;
  33.  
  34. // Looked up classes we use
  35. static Class MiscStringClass;
  36. static Class MiscClassVariableClass;
  37.  
  38. + initialize
  39. // Set the version.  Load classes, and init class variables.
  40. {
  41.     if (self == objc_lookUpClass(CLASS_NAME))  {
  42.         [self setVersion:CLASS_VERSION];
  43.  
  44.         // Load supporting classes if necessary
  45.         MiscStringClass = [self loadClassBundle:MISC_STRING_CLASS_NAME];
  46.         MiscClassVariableClass = [self loadClassBundle:
  47.                     MISC_CLASSVARIABLE_CLASS_NAME];
  48.         
  49.         // Set up class variables
  50.         _MiscClassNibName = [[MiscClassVariableClass allocFromZone:[self zone]] 
  51.                     initDoesFreeValues:YES];
  52.     }
  53.     return self;
  54. }
  55.  
  56. + startUnloading
  57. // Free our class variables.
  58. {
  59.     [_MiscClassNibName free];
  60.     return self;
  61. }
  62.  
  63. + setClassNib:(const char *)nibName
  64. // Set the nib file which contains the window this controller class controls.
  65. {
  66.     id newVal;
  67.  
  68.     if (nibName) {
  69.         newVal = [[MiscStringClass allocFromZone:[self zone]] 
  70.                 initStringValue:nibName];
  71.     } else {
  72.         newVal = nil;
  73.     }
  74.     [_MiscClassNibName setObject:newVal forClass:self];
  75.     return self;
  76. }
  77.  
  78. + (const char *)classNib
  79. // Returns the nib file name for this controller class.
  80. {
  81.     return [(MiscString *)[_MiscClassNibName getObjectForClass:self] stringValue];
  82. }
  83.  
  84. - init
  85. // Just calls the designated initializer.
  86. {
  87.     return [self initWithFrameName:NULL];
  88. }
  89.  
  90. - initWithFrameName:(const char *)theFrameName
  91. // Designated Initializer.
  92. // Initialize some instance variables.
  93. {
  94.     [super init];
  95.     nibIsLoaded = NO;
  96.     window = nil;
  97.     frameName = [[MiscStringClass allocFromZone:[self zone]] 
  98.                 initString:theFrameName];
  99.     return self;
  100. }
  101.  
  102. - free
  103. // Free our window, and frameName.
  104. {
  105.     if (window)  [window free];
  106.     [frameName free];
  107.     return [super free];
  108. }
  109.  
  110. - awake
  111. // Sets up ivars we don't archive.
  112. {
  113.     window = nil;
  114.     nibIsLoaded = NO;
  115.     return self;
  116. }
  117.  
  118. - read:(NXTypedStream *)strm
  119. // This method is probably not useful, but here it is for completeness sake.
  120. {
  121.     int classVersion;
  122.  
  123.     [super read:strm];
  124.     
  125.     classVersion = NXTypedStreamClassVersion(strm, CLASS_NAME);
  126.     
  127.     switch (classVersion)  {
  128.         case 0:        // First version.
  129.             frameName = NXReadObject(strm);
  130.             break;
  131.         default:    // bail on anything else.
  132.             NXLogError("[%s read:] class version %d cannot read "
  133.                         "instances archived with version %d", 
  134.                         CLASS_NAME, CLASS_VERSION, classVersion);
  135.             frameName = [[MiscStringClass allocFromZone:[self zone]] init];
  136.             break;
  137.     }
  138.     return self;
  139. }
  140.  
  141. - write:(NXTypedStream *)strm
  142. // This method is probably not useful, but here it is for completeness sake.
  143. {
  144.     [super write:strm];
  145.     NXWriteObject(strm, frameName);
  146.     return self;
  147. }
  148.  
  149. - setFrameName:(const char *)theFrameName
  150. // Sets the name to save the windows frame info under in the defaults 
  151. // database.
  152. {
  153.     [frameName setStringValue:theFrameName];
  154.     return self;
  155. }
  156.  
  157. - (const char *)frameName
  158. // Return the name to save the windows frame info under in the defaults 
  159. // database.
  160. {
  161.     const char *fn = [frameName stringValue];
  162.     if (!(fn) || !(*fn)) return NULL;
  163.     return fn;
  164. }
  165.  
  166. - window
  167. // Return the window.  (Returns nil if the nib file is not loaded.)
  168. {
  169.     return [self window:NO];
  170. }
  171.  
  172. - window:(BOOL)loadFlag
  173. // Return the window.  (If loadFlag is NO and window is not loaded, 
  174. // returns nil.  If loadFlag is YES, window is loaded if necessary.)
  175. {
  176.     if (loadFlag)  [self loadNibIfNeeded];
  177.     return window;
  178. }
  179.  
  180. - showWindow:sender
  181. // Show the window (loading it first if necessary).
  182. {
  183.     [self loadNibIfNeeded];
  184.     if (window)  [window makeKeyAndOrderFront:sender];
  185.     return self;
  186. }
  187.  
  188. - loadNibIfNeeded
  189. // Loads the nib file if it hasn't already been loaded.  Also performs
  190. // set up that must be deferred till the nib is loaded.
  191. {
  192.     const char *nibName = [[self class] classNib];
  193.     const char *frmName = NULL;
  194.  
  195.     if (!(nibName) || !(*nibName)) { // try to default to the class' name
  196.         nibName = [[self class] name];
  197.     }
  198.     if ((!nibIsLoaded) && (nibName) && (*nibName))  {
  199.         [self nibWillLoad];
  200.         if (![self loadNib:nibName withOwner:self fromBundle:nil]) return nil;
  201.         nibIsLoaded = YES;
  202.  
  203.         // configure window
  204.         frmName = [self frameName];
  205.         if ((frmName) && (*frmName))  { // string exists and is len > 0
  206.             [window setFrameAutosaveName:frmName];
  207.             [window setFrameUsingName:frmName];
  208.         }
  209.         [self nibDidLoad];
  210.     }
  211.     return self;
  212. }
  213.  
  214. - loadNib:(const char *)name withOwner:owner fromBundle:(NXBundle *)bundle
  215. {    // This code actually loads a .nib file
  216.     // name if NULL defaults to [self name], or [[self class] name] if
  217.     //    self doesn't have a name
  218.     // owner defaults to self if nil is passed in
  219.     // bundle defaults to the bundle for [self class] if nil is passed in
  220.     char path[MAXPATHLEN+1];
  221.     const char *realName = (name ? name :
  222.             ([self name] ? [self name] : [[self class] name]));
  223.  
  224.     // find the path to the .nib file; check appropriate bundle, getting
  225.     // the name as appropriate
  226.     if (![(bundle ? bundle : [NXBundle bundleForClass:[self class]]) 
  227.             getPath:path forResource:realName ofType:"nib"]) {
  228.         NXLogError("[%s loadNib:withOwner:fromBundle:]: failed to "
  229.                 "find nib file %s.", 
  230.                 [[self class] name], realName);
  231.         return nil;
  232.     }
  233.     if (![NXApp loadNibFile:path owner:(owner ? owner : self)
  234.             withNames:NO fromZone:[self zone]]) {
  235.         NXLogError("[%s loadNib:withOwner:fromBundle:]: failed to "
  236.                 "load nib file %s.", 
  237.                 [[self class] name], path);
  238.         return nil;
  239.     }
  240.     return self;    
  241. }
  242.  
  243. // cover methods:  (are any of these actually useful?)
  244. - loadNib
  245. {
  246.     return [self loadNib:NULL    withOwner:nil    fromBundle:nil];
  247. }
  248.  
  249. - loadNib:(const char *)name
  250. {
  251.     return [self loadNib:name    withOwner:nil    fromBundle:nil];
  252. }
  253.  
  254. - loadNib:(const char *)name withOwner:owner
  255. {
  256.     return [self loadNib:name    withOwner:owner    fromBundle:nil];
  257. }
  258.  
  259. - loadNib:(const char *)name fromBundle:bundle
  260. {
  261.     return [self loadNib:name    withOwner:nil    fromBundle:bundle];
  262. }
  263.  
  264. - nibWillLoad
  265. // This is called before our nib has been loaded.  You may override it to do
  266. // whatever needs to be done, but call super's implementation first.
  267. {
  268.     return self;
  269. }
  270.  
  271. - nibDidLoad
  272. // This is called after our nib has been loaded.  You may override it to do
  273. // whatever needs to be done, but call super's implementation first.
  274. {
  275.     return self;
  276. }
  277.  
  278.  
  279. @end
  280.