home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Nebula
/
nebula.bin
/
SourceCode
/
Palettes
/
RotationSliderPalette
/
RotationSliderCell.m
< prev
next >
Wrap
Text File
|
1993-01-30
|
6KB
|
207 lines
//
// 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