home *** CD-ROM | disk | FTP | other *** search
- //
- // RotationSliderCell.m -- written by Don Yacktman
- //
- // Copyright 1993 by Don Yacktman. All rights reserved.
- //
- // You may use this code subject to the following conditions:
- // (1) If you use this code in any applications or packages which
- // will be sold for gain (i.e. commercial, shareware, etc.) you
- // must first have a signed written agreement from the author.
- // (2) You may freely use this object in personal projects which
- // are freely redistributable at not cost to the recipient.
- // (A nominal distribution fee, like media and postage cost,
- // is OK, though.) You must include the source to this object
- // and any of your modifications in the distribution, however.
- // (3) If you make any modifications, send them to the author. If
- // any of them are useful, they will be included in any future
- // releases if you like. You must send the changes, though!
- //
-
- #import "RotationSliderCell.h"
- #import "RotationSliderWraps.h"
- #import <math.h>
-
- #define PI 3.1415926535897932384626433
-
- @implementation RotationSliderCell
-
- // Convert between a 0-360 degree angle and the slider's position. The
- // angle is used as the parameter to pass to the pswrap that does the drawing.
- // These two #defines are inverses of each other.
- #define angle(pos, min, max) (360.0 * ((pos) - (min)) / ((max) - (min)))
- #define pos(angle, min, max) ((angle) * ((max) - (min)) / 360.0 + (min))
-
- static id disabledBezelImage = nil;
- static id enabledBezelImage = nil;
- static id knobImage = nil;
-
- - init
- {
- [super init];
- value= 45.0; maxValue = 360.0; minValue = 0.0;
- [self buildImages];
- return self;
- }
-
- - awake
- {
- [super awake];
- [self buildImages];
- return self;
- }
-
- - buildImages
- {
- NXSize bezelSize = {111.0, 228.0};
- NXRect frame = {{0.0, 0.0}, {111.0, 228.0}};
- NXRect knobRect = {{85.0, 84.0}, {12.0, 12.0}};
- id tempImage;
- if (!disabledBezelImage) {
- disabledBezelImage = [[NXImage alloc] initSize:&bezelSize];
- [disabledBezelImage lockFocus];
- PSgsave();
- PSsetgray(0.0); PSsetalpha(0.0); NXRectFill(&frame); PSsetalpha(1.0);
- PSdrawBezel(0.666); PSscale(1.0, -1.0);
- PStranslate(0.0, -228.0); PSdrawBezel(0.666);
- PSgrestore();
- [disabledBezelImage unlockFocus];
- enabledBezelImage = [[NXImage alloc] initSize:&bezelSize];
- [enabledBezelImage lockFocus];
- PSgsave();
- PSsetgray(0.0); PSsetalpha(0.0); NXRectFill(&frame); PSsetalpha(1.0);
- PSdrawBezel(0.5); PSscale(1.0, -1.0);
- PStranslate(0.0, -228.0); PSdrawBezel(0.5);
- PSgrestore();
- [enabledBezelImage unlockFocus];
- tempImage = [[NXImage alloc] initSize:&bezelSize];
- [tempImage lockFocus];
- PSgsave();
- PSsetgray(0.0); PSsetalpha(0.0); NXRectFill(&frame); PSsetalpha(1.0);
- PSdrawKnob(45.0); PSscale(1.0, -1.0);
- PStranslate(0.0, -228.0); PSdrawKnob(45.0);
- PSgrestore();
- [tempImage unlockFocus];
- knobImage = [[NXImage alloc] initFromImage:tempImage rect:&knobRect];
- }
- return self;
- }
-
- - calcCellSize:(NXSize *)theSize inRect:(const NXRect *)aRect
- {
- theSize->width = 111.0;
- theSize->height = 112.0;
- return self;
- }
-
- - (BOOL)startTrackingAt:(const NXPoint *)startPoint inView:controlView
- {
- float x, y, radius;
- if (imFlipped) y = 55.5 - startPoint->y;
- else y = startPoint->y - 55.5;
- x = startPoint->x - 55.5;
- radius = x * x + y * y;
- if ((radius < 44.0 * 44.0) || (radius > 56.0 * 56.0)) return NO;
- return [super startTrackingAt:startPoint inView:controlView];
- }
-
- - (BOOL)continueTracking:(const NXPoint *)lastPoint
- at:(const NXPoint *)currentPoint inView:controlView
- {
- NXPoint nothing = {50.0, 50.0};
- NXRect eraseRect; NXPoint position; id bezel;
- float ang, x, y, oldang, oldx, oldy;
- if (imFlipped) y = 55.5 - currentPoint->y;
- else y = currentPoint->y - 55.5;
- x = currentPoint->x - 55.5;
- ang = atan(y / x) * 180 / PI;
- if (x < 0) ang += 180.0;
- if (ang < 0) ang += 360.0;
- if (lastPoint) {
- if (imFlipped) oldy = 55.5 - lastPoint->y;
- else oldy = lastPoint->y - 55.5;
- oldx = lastPoint->x - 55.5;
- oldang = atan(oldy / oldx) * 180 / PI;
- if (oldx < 0) oldang += 180.0;
- if (oldang < 0) oldang += 360.0;
- oldx = cos(oldang * PI / 180.0) * 50.0 + 47.0;
- oldy = sin(oldang * PI / 180.0) * 50.0 + 47.0;
- NXSetRect(&eraseRect, oldx, oldy, 17.0, 16.0);
- } else {
- oldang = angle(value, minValue, maxValue);
- oldx = cos(oldang * PI / 180.0) * 50.0 + 47.0;
- oldy = sin(oldang * PI / 180.0) * 50.0 + 47.0;
- NXSetRect(&eraseRect, oldx, oldy, 17.0, 16.0);
- }
- NXIntegralRect(&eraseRect);
- x = cos(ang * PI / 180.0) * 50.0 + 50.0;
- y = sin(ang * PI / 180.0) * 50.0 + 49.0;
- position.x = x; position.y = y;
- value = pos(ang, minValue, maxValue);
- PSgsave();
- if (imFlipped) {
- PSscale(1.0, -1.0);
- PStranslate(0.0, -111.0);
- }
- bezel = (cFlags1.disabled ? disabledBezelImage : enabledBezelImage);
- [bezel composite:NX_SOVER fromRect:&eraseRect toPoint:&(eraseRect.origin)];
- if ((value == minValue) || (value == maxValue))
- position.x -= 1.0; // a hack to fix a weird bug
- [knobImage composite:NX_SOVER toPoint:&position];
- PSgrestore();
- [[controlView window] flushWindow];
- return YES;
- }
-
- - drawBarInside:(const NXRect *)cellFrame flipped:(BOOL)flipped
- {
- NXRect frame = {{0.0, 0.0}, {111.0, 112.0}};
- id bezel = (cFlags1.disabled ? disabledBezelImage : enabledBezelImage);
- PSgsave();
- if (flipped) {
- PSscale(1.0, -1.0);
- PStranslate(0.0, -111.0);
- imFlipped = YES;
- }
- [bezel composite:NX_SOVER fromRect:&frame toPoint:&(frame.origin)];
- PSgrestore();
- return self;
- }
-
- - drawKnob:(const NXRect *)knobRect
- {
- NXRect frame = {{0.0, 0.0}, {111.0, 111.0}};
- NXPoint position; float ang; float range = maxValue - minValue;
- id bezel = (cFlags1.disabled ? disabledBezelImage : enabledBezelImage);
- PSgsave();
- if (imFlipped) {
- PSscale(1.0, -1.0);
- PStranslate(0.0, -111.0);
- }
- [bezel composite:NX_SOVER fromRect:&frame toPoint:&(frame.origin)];
- ang = angle(value, minValue, maxValue);
- position.x = cos(ang * PI / 180.0) * 50.0 + 50.0;
- if ((value == minValue) || (value == maxValue))
- position.x -= 1.0; // a hack to fix a weird bug
- position.y = sin(ang * PI / 180.0) * 50.0 + 49.0;
- [knobImage composite:NX_SOVER toPoint:&position];
- PSgrestore();
- return self;
- }
-
- - drawSelf:(const NXRect *)cellFrame inView:controlView
- {
- trackRect = *cellFrame;
- if ([controlView isFlipped]) imFlipped = YES;
- [self drawKnob:cellFrame];
- return self;
- }
-
- - getKnobRect:(NXRect *)knobRect flipped:(BOOL)flipped
- {
- [super getKnobRect:knobRect flipped:flipped];
- return self;
- }
-
-
- @end
-