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

  1. //
  2. //    RotationSliderCell.m -- written by Don Yacktman
  3. //
  4. //    Copyright 1993 by Don Yacktman.  All rights reserved.
  5. //
  6. //    You may use this code subject to the following conditions:
  7. //    (1) If you use this code in any applications or packages which
  8. //        will be sold for gain (i.e. commercial, shareware, etc.) you
  9. //        must first have a signed written agreement from the author.
  10. //    (2) You may freely use this object in personal projects which
  11. //        are freely redistributable at not cost to the recipient.
  12. //        (A nominal distribution fee, like media and postage cost,
  13. //        is OK, though.)  You must include the source to this object
  14. //        and any of your modifications in the distribution, however.
  15. //    (3) If you make any modifications, send them to the author.  If
  16. //        any of them are useful, they will be included in any future
  17. //        releases if you like.  You must send the changes, though!
  18. //
  19.  
  20. #import "RotationSliderCell.h"
  21. #import "RotationSliderWraps.h"
  22. #import <math.h>
  23.  
  24. #define PI 3.1415926535897932384626433
  25.  
  26. @implementation RotationSliderCell
  27.  
  28. // Convert between a 0-360 degree angle and the slider's position.  The
  29. // angle is used as the parameter to pass to the pswrap that does the drawing.
  30. // These two #defines are inverses of each other.
  31. #define angle(pos, min, max) (360.0 * ((pos) - (min)) / ((max) - (min)))
  32. #define pos(angle, min, max) ((angle) * ((max) - (min)) / 360.0 + (min))
  33.  
  34. static id disabledBezelImage = nil;
  35. static id enabledBezelImage = nil;
  36. static id knobImage = nil;
  37.  
  38. - init
  39. {
  40.     [super init];
  41.     value= 45.0; maxValue = 360.0; minValue = 0.0;
  42.     [self buildImages];
  43.     return self;
  44. }
  45.  
  46. - awake
  47. {
  48.     [super awake];
  49.     [self buildImages];
  50.     return self;
  51. }
  52.  
  53. - buildImages
  54. {
  55.     NXSize bezelSize = {111.0, 228.0};
  56.     NXRect frame = {{0.0, 0.0}, {111.0, 228.0}};
  57.     NXRect knobRect = {{85.0, 84.0}, {12.0, 12.0}};
  58.     id tempImage;
  59.     if (!disabledBezelImage) {
  60.         disabledBezelImage = [[NXImage alloc] initSize:&bezelSize];
  61.         [disabledBezelImage lockFocus];
  62.         PSgsave();
  63.         PSsetgray(0.0); PSsetalpha(0.0); NXRectFill(&frame); PSsetalpha(1.0);
  64.         PSdrawBezel(0.666); PSscale(1.0, -1.0);
  65.         PStranslate(0.0, -228.0); PSdrawBezel(0.666);
  66.         PSgrestore();
  67.         [disabledBezelImage unlockFocus];
  68.         enabledBezelImage = [[NXImage alloc] initSize:&bezelSize];
  69.         [enabledBezelImage lockFocus];
  70.         PSgsave();
  71.         PSsetgray(0.0); PSsetalpha(0.0); NXRectFill(&frame); PSsetalpha(1.0);
  72.         PSdrawBezel(0.5); PSscale(1.0, -1.0);
  73.         PStranslate(0.0, -228.0); PSdrawBezel(0.5);
  74.         PSgrestore();
  75.         [enabledBezelImage unlockFocus];
  76.         tempImage = [[NXImage alloc] initSize:&bezelSize];
  77.         [tempImage lockFocus];
  78.         PSgsave();
  79.         PSsetgray(0.0); PSsetalpha(0.0); NXRectFill(&frame); PSsetalpha(1.0);
  80.         PSdrawKnob(45.0); PSscale(1.0, -1.0);
  81.         PStranslate(0.0, -228.0); PSdrawKnob(45.0);
  82.         PSgrestore();
  83.         [tempImage unlockFocus];
  84.         knobImage = [[NXImage alloc] initFromImage:tempImage rect:&knobRect];
  85.     }
  86.     return self;
  87. }
  88.  
  89. - calcCellSize:(NXSize *)theSize inRect:(const NXRect *)aRect
  90. {
  91.     theSize->width = 111.0;
  92.     theSize->height = 112.0;
  93.     return self;
  94. }
  95.  
  96. - (BOOL)startTrackingAt:(const NXPoint *)startPoint inView:controlView
  97. {
  98.     float x, y, radius;
  99.     if (imFlipped) y = 55.5 - startPoint->y;
  100.     else y = startPoint->y - 55.5;
  101.     x = startPoint->x - 55.5;
  102.     radius = x * x + y * y;
  103.     if ((radius < 44.0 * 44.0) || (radius > 56.0 * 56.0)) return NO;
  104.     return [super startTrackingAt:startPoint inView:controlView];
  105. }
  106.  
  107. - (BOOL)continueTracking:(const NXPoint *)lastPoint
  108.         at:(const NXPoint *)currentPoint inView:controlView
  109. {
  110.     NXPoint nothing = {50.0, 50.0};
  111.     NXRect eraseRect; NXPoint position; id bezel;
  112.     float ang, x, y, oldang, oldx, oldy;
  113.     if (imFlipped) y = 55.5 - currentPoint->y;
  114.     else y = currentPoint->y - 55.5;
  115.     x = currentPoint->x - 55.5;
  116.     ang = atan(y / x) * 180 / PI;
  117.     if (x < 0) ang += 180.0;
  118.     if (ang < 0) ang += 360.0;
  119.     if (lastPoint) {
  120.         if (imFlipped) oldy = 55.5 - lastPoint->y;
  121.         else oldy = lastPoint->y - 55.5;
  122.         oldx = lastPoint->x - 55.5;
  123.         oldang = atan(oldy / oldx) * 180 / PI;
  124.         if (oldx < 0) oldang += 180.0;
  125.         if (oldang < 0) oldang += 360.0;
  126.         oldx = cos(oldang * PI / 180.0) * 50.0 + 47.0;
  127.         oldy = sin(oldang * PI / 180.0) * 50.0 + 47.0;
  128.         NXSetRect(&eraseRect, oldx, oldy, 17.0, 16.0);
  129.     } else {
  130.         oldang = angle(value, minValue, maxValue);
  131.         oldx = cos(oldang * PI / 180.0) * 50.0 + 47.0;
  132.         oldy = sin(oldang * PI / 180.0) * 50.0 + 47.0;
  133.         NXSetRect(&eraseRect, oldx, oldy, 17.0, 16.0);
  134.     }
  135.     NXIntegralRect(&eraseRect);
  136.     x = cos(ang * PI / 180.0) * 50.0 + 50.0;
  137.     y = sin(ang * PI / 180.0) * 50.0 + 49.0;
  138.     position.x = x; position.y = y;
  139.     value = pos(ang, minValue, maxValue);
  140.     PSgsave();
  141.     if (imFlipped) {
  142.         PSscale(1.0, -1.0);
  143.         PStranslate(0.0, -111.0);
  144.     }
  145.     bezel = (cFlags1.disabled ? disabledBezelImage : enabledBezelImage);
  146.     [bezel composite:NX_SOVER fromRect:&eraseRect toPoint:&(eraseRect.origin)];
  147.     if ((value == minValue) || (value == maxValue))
  148.         position.x -= 1.0; // a hack to fix a weird bug
  149.     [knobImage composite:NX_SOVER toPoint:&position];
  150.     PSgrestore();
  151.     [[controlView window] flushWindow];
  152.     return YES;
  153. }
  154.  
  155. - drawBarInside:(const NXRect *)cellFrame flipped:(BOOL)flipped
  156. {
  157.     NXRect frame = {{0.0, 0.0}, {111.0, 112.0}};
  158.     id bezel = (cFlags1.disabled ? disabledBezelImage : enabledBezelImage);
  159.     PSgsave();
  160.     if (flipped) {
  161.         PSscale(1.0, -1.0);
  162.         PStranslate(0.0, -111.0);
  163.         imFlipped = YES;
  164.     }
  165.     [bezel composite:NX_SOVER fromRect:&frame toPoint:&(frame.origin)];
  166.     PSgrestore();
  167.     return self;
  168. }
  169.  
  170. - drawKnob:(const NXRect *)knobRect
  171. {
  172.     NXRect frame = {{0.0, 0.0}, {111.0, 111.0}};
  173.     NXPoint position; float ang; float range = maxValue - minValue;
  174.     id bezel = (cFlags1.disabled ? disabledBezelImage : enabledBezelImage);
  175.     PSgsave();
  176.     if (imFlipped) {
  177.         PSscale(1.0, -1.0);
  178.         PStranslate(0.0, -111.0);
  179.     }
  180.     [bezel composite:NX_SOVER fromRect:&frame toPoint:&(frame.origin)];
  181.     ang = angle(value, minValue, maxValue);
  182.     position.x = cos(ang * PI / 180.0) * 50.0 + 50.0;
  183.     if ((value == minValue) || (value == maxValue))
  184.         position.x -= 1.0; // a hack to fix a weird bug
  185.     position.y = sin(ang * PI / 180.0) * 50.0 + 49.0;
  186.     [knobImage composite:NX_SOVER toPoint:&position];
  187.     PSgrestore();
  188.     return self;
  189. }
  190.  
  191. - drawSelf:(const NXRect *)cellFrame inView:controlView
  192. {
  193.     trackRect = *cellFrame;
  194.     if ([controlView isFlipped]) imFlipped = YES;
  195.     [self drawKnob:cellFrame];
  196.     return self;
  197. }
  198.  
  199. - getKnobRect:(NXRect *)knobRect flipped:(BOOL)flipped
  200. {
  201.     [super getKnobRect:knobRect flipped:flipped];
  202.     return self;
  203. }
  204.  
  205.  
  206. @end
  207.