home *** CD-ROM | disk | FTP | other *** search
- // Written by Don Yacktman Copyright (c) 1994 by Don Yacktman.
- // Version 1.0. All rights reserved.
- //
- // This notice may not be removed from this source code.
- //
- // This object is included in the MiscKit by permission from the author
- // and its use is governed by the MiscKit license, found in the file
- // "LICENSE.rtf" in the MiscKit distribution. Please refer to that file
- // for a list of all applicable permissions and restrictions.
- //
-
- #import "CounterView.h"
-
- @implementation CounterView
-
- - initFrame:(const NXRect *)frm
- {
- [super initFrame:frm];
- running = NO;
- [self counter];
- [self reset];
- return self;
- }
-
- - drawSelf:(NXRect *)rects :(int)rectCount
- {
- NXRect theBorder;
- [self getFrame:&theBorder];
- theBorder.origin.x = 0.0;
- theBorder.origin.y = 0.0;
- NXDrawGrayBezel(&theBorder, NULL);
- NXInsetRect(&theBorder, 4.0, 4.0);
- if (running) NXSetColor(NX_COLORGREEN);
- else NXSetColor(NX_COLORRED);
- NXRectFill(&theBorder);
- return self;
- }
-
- - keyDown:(NXEvent *)myevent
- {
- PSobscurecursor(); // subclasses which override need to do this.
- if (myevent->data.key.charSet == NX_ASCIISET &&
- (myevent->flags&(NX_CONTROLMASK|NX_ALTERNATEMASK|NX_COMMANDMASK)) == 0)
- {
- if ((myevent->data.key.charCode) == ' ') { // allow pause
- [self tap:nil];
- } else if ((myevent->data.key.charCode) == 's') { // allow new game
- if (running) [self stop:nil];
- else [self start:nil];
- } else if ((myevent->data.key.charCode) == 'r') { // allow new game
- [self clear:nil];
- }
- }
- return self;
- }
-
- - mouseDown:(NXEvent *)event
- {
- if (!running) {
- [self clear:nil];
- [self start:nil];
- } else [self tap:nil];
- return self;
- }
-
- - (MiscStopwatch *)counter
- {
- if (!counter) counter = [[MiscStopwatch alloc] init];
- return counter;
- }
-
- - reset
- {
- [beatsPerMeasure setIntValue:4];
- [self clear:nil];
- return self;
- }
-
- - clear:sender
- {
- beatsCounted = 0;
- [self stop:nil];
- [beatsPerMinute setIntValue:0];
- [measuresPerMinute setIntValue:0];
- [secondsElapsed setIntValue:0];
- [[self counter] clearTiming:nil];
- [beatsPerMinute setBackgroundGray:0.666];
- [measuresPerMinute setBackgroundGray:0.666];
- [self update];
- return self;
- }
-
- - start:sender
- {
- running = YES;
- [[self counter] continueTiming:nil];
- [beatsPerMinute setBackgroundGray:1.0];
- [measuresPerMinute setBackgroundGray:1.0];
- [self update];
- [self enableButtons:YES :NO :YES :YES];
- return self;
- }
-
- - stop:sender
- {
- if (running) [self tap:nil];
- running = NO;
- [[self counter] pauseTiming:nil];
- [beatsPerMinute setBackgroundGray:0.666];
- [measuresPerMinute setBackgroundGray:0.666];
- [self update];
- [self enableButtons:YES :YES :NO :NO];
- return self;
- }
-
- - tap:sender
- {
- int bm; id sc = [self counter];
- float seconds, bpm, mpm;
-
- if (!running) return [self start:nil];
- // get the basic infor we need
- beatsCounted++;
- [[self counter] calcElapsedTime:nil];
- seconds = [sc microsecond] / MISC_TIME_MAX_MICROSECONDS +
- [sc second] + 60 * [sc minute];
- bm = [beatsPerMeasure intValue];
-
- // avoid divide by zero
- if (bm < 1) bm = 1;
- if (seconds < 1) seconds = 1;
-
- // do calculations
- bpm = floor((beatsCounted * 600) / seconds) / 10;
- mpm = floor((bpm * 10) / bm) / 10;
-
- // update the interface
- [beatsPerMinute setFloatValue:bpm];
- [measuresPerMinute setFloatValue:mpm];
- [secondsElapsed setIntValue:seconds];
- return self;
- }
-
- - enableButtons:(BOOL)cb :(BOOL)sb :(BOOL)sb2 :(BOOL)tb
- {
- [clearButton setEnabled:cb];
- [startButton setEnabled:sb];
- [stopButton setEnabled:sb2];
- [tapButton setEnabled:tb];
- return self;
- }
-
- - (BOOL)acceptsFirstMouse { return YES; }
- - (BOOL)acceptsFirstResponder { return YES; }
-
- @end
-