home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / SourceCode / MiscKit1.7.1 / MiscKit / Examples / BPM / CounterView.m < prev    next >
Encoding:
Text File  |  1995-04-12  |  3.5 KB  |  157 lines

  1. //        Written by Don Yacktman Copyright (c) 1994 by Don Yacktman.
  2. //                Version 1.0.  All rights reserved.
  3. //
  4. //        This notice may not be removed from this source code.
  5. //
  6. //    This object is included in the MiscKit by permission from the author
  7. //    and its use is governed by the MiscKit license, found in the file
  8. //    "LICENSE.rtf" in the MiscKit distribution.  Please refer to that file
  9. //    for a list of all applicable permissions and restrictions.
  10. //    
  11.  
  12. #import "CounterView.h"
  13.  
  14. @implementation CounterView
  15.  
  16. - initFrame:(const NXRect *)frm
  17. {
  18.     [super initFrame:frm];
  19.     running = NO;
  20.     [self counter];
  21.     [self reset];
  22.     return self;
  23. }
  24.  
  25. - drawSelf:(NXRect *)rects :(int)rectCount
  26. {
  27.     NXRect theBorder;
  28.     [self getFrame:&theBorder];
  29.     theBorder.origin.x = 0.0;
  30.     theBorder.origin.y = 0.0;
  31.     NXDrawGrayBezel(&theBorder, NULL);
  32.     NXInsetRect(&theBorder, 4.0, 4.0);
  33.     if (running) NXSetColor(NX_COLORGREEN);
  34.     else NXSetColor(NX_COLORRED);
  35.     NXRectFill(&theBorder);
  36.     return self;
  37. }
  38.  
  39. - keyDown:(NXEvent *)myevent
  40. {
  41.     PSobscurecursor();  // subclasses which override need to do this.
  42.     if (myevent->data.key.charSet == NX_ASCIISET &&
  43.         (myevent->flags&(NX_CONTROLMASK|NX_ALTERNATEMASK|NX_COMMANDMASK)) == 0)
  44.     {    
  45.         if ((myevent->data.key.charCode) == ' ') { // allow pause
  46.             [self tap:nil];
  47.         } else if ((myevent->data.key.charCode) == 's') { // allow new game
  48.             if (running) [self stop:nil];
  49.             else [self start:nil];
  50.         } else if ((myevent->data.key.charCode) == 'r') { // allow new game
  51.             [self clear:nil];
  52.         }
  53.     }
  54.     return self;
  55. }
  56.  
  57. - mouseDown:(NXEvent *)event
  58. {
  59.     if (!running) {
  60.         [self clear:nil];
  61.         [self start:nil];
  62.     } else [self tap:nil];
  63.     return self;
  64. }
  65.  
  66. - (MiscStopwatch *)counter
  67. {
  68.     if (!counter) counter = [[MiscStopwatch alloc] init];
  69.     return counter;
  70. }
  71.  
  72. - reset
  73. {
  74.     [beatsPerMeasure setIntValue:4];
  75.     [self clear:nil];
  76.     return self;
  77. }
  78.  
  79. - clear:sender
  80. {
  81.     beatsCounted = 0;
  82.     [self stop:nil];
  83.     [beatsPerMinute setIntValue:0];
  84.     [measuresPerMinute setIntValue:0];
  85.     [secondsElapsed setIntValue:0];
  86.     [[self counter] clearTiming:nil];
  87.     [beatsPerMinute setBackgroundGray:0.666];
  88.     [measuresPerMinute setBackgroundGray:0.666];
  89.     [self update];
  90.     return self;
  91. }
  92.  
  93. - start:sender
  94. {
  95.     running = YES;
  96.     [[self counter] continueTiming:nil];
  97.     [beatsPerMinute setBackgroundGray:1.0];
  98.     [measuresPerMinute setBackgroundGray:1.0];
  99.     [self update];
  100.     [self enableButtons:YES :NO :YES :YES];
  101.     return self;
  102. }
  103.  
  104. - stop:sender
  105. {
  106.     if (running) [self tap:nil];
  107.     running = NO;
  108.     [[self counter] pauseTiming:nil];
  109.     [beatsPerMinute setBackgroundGray:0.666];
  110.     [measuresPerMinute setBackgroundGray:0.666];
  111.     [self update];
  112.     [self enableButtons:YES :YES :NO :NO];
  113.     return self;
  114. }
  115.  
  116. - tap:sender
  117. {
  118.     int bm; id sc = [self counter];
  119.     float seconds, bpm, mpm;
  120.  
  121.     if (!running) return [self start:nil];
  122.     // get the basic infor we need
  123.     beatsCounted++;
  124.     [[self counter] calcElapsedTime:nil];
  125.     seconds = [sc microsecond] / MISC_TIME_MAX_MICROSECONDS +
  126.             [sc second] + 60 * [sc minute];
  127.     bm = [beatsPerMeasure intValue];
  128.     
  129.     // avoid divide by zero
  130.     if (bm < 1) bm = 1;
  131.     if (seconds < 1) seconds = 1;
  132.  
  133.     // do calculations
  134.     bpm = floor((beatsCounted * 600) / seconds) / 10;
  135.     mpm = floor((bpm * 10) / bm) / 10;
  136.  
  137.     // update the interface
  138.     [beatsPerMinute setFloatValue:bpm];
  139.     [measuresPerMinute setFloatValue:mpm];
  140.     [secondsElapsed setIntValue:seconds];
  141.     return self;
  142. }
  143.  
  144. - enableButtons:(BOOL)cb :(BOOL)sb :(BOOL)sb2 :(BOOL)tb
  145. {
  146.     [clearButton setEnabled:cb];
  147.     [startButton setEnabled:sb];
  148.     [stopButton setEnabled:sb2];
  149.     [tapButton setEnabled:tb];
  150.     return self;
  151. }
  152.  
  153. - (BOOL)acceptsFirstMouse { return YES; }
  154. - (BOOL)acceptsFirstResponder { return YES; }
  155.  
  156. @end
  157.