home *** CD-ROM | disk | FTP | other *** search
/ Peanuts NeXT Software Archives / Peanuts-Update.iso / Rhapsody / developer / examples / LocalizationExample.5.0.m.I.bs.tz / LocalizationExample.5.0.m.I.bs / LocalizationExample.5.0.I.bs / Source / Spewer.m < prev   
Encoding:
Text File  |  1997-11-03  |  5.7 KB  |  167 lines

  1.  
  2. // Copyright (c) 1997 by Don Yacktman
  3. // All rights reserved.
  4. // Permission to use this code in your application, whether
  5. // commercial, shareware, or freeware, is granted.
  6. // This notice may not be removed or altered.
  7.  
  8.  
  9. #import "Spewer.h"
  10. #import "FlyingWindow.h"
  11. #import "Animator.h"
  12. #import <libc.h>
  13.  
  14. @implementation Spewer:NSObject
  15.  
  16. - init
  17. {
  18.     [super init];
  19.     // seed the random number generator with the current time.
  20.     // This call should really only be done once, before the random
  21.     // number generator is ever used.  Since this object is typically
  22.     // only instantiated once so that's not a problem.
  23.     srandom(time(0));
  24.     // clear this out, since we've not been started yet.
  25.     initiator = nil;
  26.     // get an animator instance to help us run the animation.
  27.     animator = [[Animator allocWithZone:[self zone]] initChronon:0.05
  28.             adaptation:0.0 target:self action:@selector(move:)
  29.             autoStart:NO eventMask:0];
  30.     // set up an extra list used for swapping during animation
  31.     _extraList = [[NSMutableArray allocWithZone:[self zone]] init];
  32.     // set up the list of extra, idle windows
  33.     idleWindows = [[NSMutableArray allocWithZone:[self zone]] init];
  34.     // set up the list of active windows
  35.     windowList = [[NSMutableArray allocWithZone:[self zone]] init];
  36.     // it is not currently OK to create ne windows.
  37.     createOK = NO;
  38.     return self;
  39. }
  40.  
  41. - start:sender
  42. {
  43.     // start the animation.  It is OK to instantiate new windows.
  44.     createOK = YES;
  45.     // the sender is the one who started us off, so cache that info
  46.     initiator = sender;
  47.     // get a new window so that we have at least one window to animate
  48.     [self addWindow];
  49.     // start the animation
  50.     [animator startEntry];
  51.     return self;
  52. }
  53.  
  54. - (void)stop:(id)sender
  55. {
  56.     // we need to stop the animation, but need all the windows to
  57.     // fall off the screen first.  So we tell ourself that the
  58.     // initiator is gone and disallow creation of new windows.
  59.     createOK = NO;
  60.     initiator = nil;
  61. }
  62.  
  63. - (BOOL)windowShouldClose:(id)sender
  64. {
  65.     // if the window is closing, then we automatically stop the
  66.     // animation.  Make sure we are the winow's delegate (hooked
  67.     // up as such in IB) or else we won't get this message!
  68.     [self stop:self];
  69.     return YES;
  70. }
  71.  
  72. - (void)dealloc
  73. { // clean out any windows, remove the timed antry and free everything
  74.     int i;
  75.     // stop the animation and get rid of the animator
  76.     [animator stopEntry];
  77.     [animator release];
  78.     animator = nil;
  79.     // get rid of all our windows--get them off the screen
  80.     for (i=0; i<[windowList count]; i++) {
  81.         [[windowList objectAtIndex:i] orderOut:self];
  82.     }
  83.     // free the active window list and its contents
  84.     [windowList release];
  85.     windowList = nil;
  86.     // free the idle window list and its contents
  87.     [idleWindows release];
  88.     idleWindows = nil;
  89.     [super dealloc];
  90.     return;
  91. }
  92.  
  93. - addWindow
  94. {    // put up a new window on the screen
  95.     NSPoint theCenterPoint;
  96.     NSRect senderFrame;
  97.     id newWindow = nil;
  98.  
  99.     // if we're not allowed to start any new windows, then return immediately
  100.     if (!createOK) return nil;
  101.     // find the point where the new window should appear on the screen.
  102.     // find out the frame of the control which sent the -start: message
  103.     senderFrame = [initiator frame];
  104.     // Get the center point of the initiator's frame
  105.     theCenterPoint.x = NSMinX(senderFrame) + NSWidth(senderFrame) / 2;
  106.     theCenterPoint.y = NSMinY(senderFrame) + NSHeight(senderFrame) / 2;
  107.     // Convert the point from view to screen coordinates
  108.     theCenterPoint = [[initiator window] convertBaseToScreen:theCenterPoint];
  109.     // recycle a window if there are any idle ones; otherwise make a new one
  110.     // get an idle window
  111.     newWindow = [idleWindows lastObject];
  112.     // if we got one, then take it out of the list of idle windows
  113.     if (newWindow) [idleWindows removeLastObject];
  114.     // if there weeren't any idle windows, then create a new one and set it
  115.     // to appear at the point calculated above.  If we found an idle window,
  116.     // then get it to set itself up as the same point.
  117.     if (!newWindow) newWindow = [[FlyingWindow allocWithZone:[self zone]]
  118.             initAt:&theCenterPoint];
  119.     else [newWindow reInitAt:&theCenterPoint];
  120.     // add the new window to the list of active windows.
  121.     [windowList addObject:newWindow];
  122.     return self;
  123. }
  124.  
  125. - move:sender
  126. {
  127.     // get a new active list
  128.     int i; id newList = _extraList;
  129.  
  130.     // add any new windows spewing about if necessary...
  131.     // if we don't have too many windows out already, then check
  132.     // against a random number to decide if we should add a new
  133.     // window.  The larger "FREQUENCY" is, the longer the average
  134.     // interval will be between new windows coming onto the screen.
  135.     if (([windowList count] < MAX_SPEWS) && !(random() % FREQUENCY)) {
  136.         [self addWindow];
  137.     }
  138.  
  139.     // move all the active windows
  140.     for (i=0; i<[windowList count]; i++) [[windowList objectAtIndex:i] move];
  141.  
  142.     // remove any windows that left the screen
  143.     for (i=0; i<[windowList count]; i++) {
  144.         id theWindow = [windowList objectAtIndex:i];
  145.         // if the window is on the screen, transfer it to a new active list
  146.         if ([theWindow onScreen]) [newList addObject:theWindow];
  147.         // windows that left the screen are taken out of the animation and moved to the idle list
  148.         else {
  149.             [theWindow orderOut:self];
  150.             [idleWindows addObject:theWindow]; // put in recycler
  151.         }
  152.     }
  153.     // make sure no stray windows were left behind.
  154.     [windowList removeAllObjects];
  155.     // get rid of the old active list and set up the new one.
  156.     _extraList = windowList;
  157.     windowList = newList;
  158.     // if there are no more windows in the active list, and it is no longer
  159.     // OK to create new ones, then the animation has ended, so we'll stop
  160.     // the timer.
  161.     if (([windowList count] < 1) && !(createOK))
  162.         // stop TE after all windows gone
  163.         [animator stopEntry];
  164.     return self;
  165. }
  166.  
  167. @end