home *** CD-ROM | disk | FTP | other *** search
- /*
- * Filename: CircularSlider.m
- * Created : Sat 24 21:25:44 1991
- * Author : Vince DeMarco
- * <vince@whatnxt.cuc.ab.ca>
- *
- * Version 1.0.1
- */
-
- /* Generated by Interface Builder */
-
- #import "CircularSlider.h"
- #include <math.h>
- #import <appkit/Application.h>
- #import <appkit/Panel.h>
- #import <dpsclient/event.h>
- #import <dpsclient/wraps.h>
- #import <appkit/graphics.h>
-
- #import "wraps.h"
-
- inline static float angle(float x, float y);
-
- @implementation CircularSlider
-
- // Given a x,y point on a cart coordinate system this function returns the angle from
- // the positive side of the Y- axis
- // ^
- // |
- // |\
- // <____|_|__>
- // | |
- // |<-
- // |
-
- inline static float angle(float x, float y)
- {
- float result;
-
- if (y >= 0){ /* Quadrants 1,4 */
- if ( x >= 0){ /* Quadrant 1 */
- result = fabs(atan(fabs(x/y)));
- result *= (180/M_PI);
- return(result);
- }else{ /* Quadrant 4 */
- result = fabs(atan(fabs(y/x)));
- result *= (180/M_PI);
- return(result+270.0);
- }
- }else{ /* Quadrants 2,3 */
- if ( x >= 0){ /* Quadrant 2 */
- result = fabs(atan(fabs(y/x)));
- result *= (180/M_PI);
- return(result+90.0);
- }else{ /* Quadrant 3 */
- result = fabs(atan(fabs(x/y)));
- result *= (180/M_PI);
- return(result+180.0);
- }
- }
- }
-
- - initFrame:(NXRect *)nf
- {
- self = [super initFrame:nf];
- [self allocateGState];
- x = nf->size.width/2;
- y = nf->size.height/2;
- radius = ( x < y ? x : y) - 4;
- currentang = 0.0;
- maxang = 360.0;
- CircFlags.continuous = 1; // By Default messages are continuously sent
- return(self);
- }
-
- - setContinuous:(BOOL)flag
- {
- if (flag == NO)
- CircFlags.continuous = 0;
- else
- CircFlags.continuous = 1;
- return(self);
- }
-
- - (BOOL)isContinuous
- {
- if (CircFlags.continuous == 1)
- return YES;
- else
- return NO;
- }
-
- - (float)floatValue
- {
- return(currentang);
- }
-
- - (double)doubleValue
- {
- return((double)currentang);
- }
-
- - (int)intValue
- {
- return((int)currentang);
- }
-
- - setDoubleValue:(double)value
- {
- [self setFloatValue:(float)value];
- return(self);
- }
-
- - setFloatValue:(float)value
- {
- if (value <= maxang){
- currentang = value;
- }else{
- currentang = maxang;
- }
- [self display];
- return(self);
- }
-
- - setIntValue:(int)value
- {
- [self setFloatValue:(float)value];
- return(self);
- }
-
- - setTheMaxValue:(float)afloat
- {
- maxang = afloat;
- return(self);
- }
-
- - (float)theMaxValue
- {
- return(maxang);
- }
-
- - takeDoubleValueFrom:sender
- {
- float newValue;
-
- newValue = [sender floatValue];
- if ((newValue != currentang) && (newValue <= maxang)){
- currentang = newValue;
- [self display];
- }
- return(self);
- }
-
- - takeFloatValueFrom:sender
- {
- return([self takeDoubleValueFrom:sender]);
- }
-
- - takeIntValueFrom:sender
- {
- return([self takeDoubleValueFrom:sender]);
- }
-
- - setAction:(SEL)aSelector
- {
- _action = aSelector;
- return(self);
- }
-
- - setTarget:anObject
- {
- _target = anObject;
- return(self);
- }
-
- - target
- {
- return( _target);
- }
-
- - (SEL)action
- {
- return( _action);
- }
-
- - drawSelf:(const NXRect *)rects : (int)count
- {
- x = bounds.size.width/2;
- y = bounds.size.height/2;
- radius = ( x < y ? x : y) - 4;
- if (conFlags.enabled == 1){ /* Draw the 3D raised box first if it has been enabled */
- //PSdrawRectangle(bounds.origin.x,bounds.origin.y,bounds.size.width - 2,bounds.size.height);
- NXDrawButton(&bounds, &bounds);
- }
- PSdrawCircSlider(bounds.size.height,bounds.size.width,x,y,radius,currentang); // Draw the actual slider
- return(self);
- }
-
- - mouseDown:(NXEvent *)theEvent
- {
- int looping; /* Flag for while in modal loop */
- int oldMask; /* Old event mask */
- NXPoint startPoint; /* Location of mouseDown */
- NXPoint currentPoint; /* Location of mouseDragged/mouseUp */
- float newangle = 0; /* angle of current mouseDown/mouseDragged/mouseUp point */
- float scalex = bounds.size.height / bounds.size.width;
- float scaley = bounds.size.width / bounds.size.height;
-
- if (conFlags.enabled == 1){ /* If CircularSlider is disabled don't allow any
- * mouseDown events, just ignore them.
- */
-
- /* Allow mouseDragged events */
- oldMask = [window addToEventMask:NX_MOUSEDRAGGEDMASK];
-
- /* Get the location of the mouseDown in view coordinates */
- startPoint = theEvent->location;
- [self convertPoint:&startPoint fromView:nil];
-
- /* Initialize the drawing context */
- [self lockFocus];
-
- // Adjust the mouseDown event's location if the Slider has been
- // scaled in either the x or y direction
-
- if (scalex > scaley ){
- newangle = angle(scalex*(startPoint.x-(x)),startPoint.y-(y));
- }else
- if (scalex < scaley ){
- newangle = angle(startPoint.x-(x),scaley*(startPoint.y-(y)));
- }else
- if (scalex = scaley ){
- newangle = angle(startPoint.x-(x),startPoint.y-(y));
- }
- if (newangle <= maxang)
- currentang = newangle;
- else
- currentang = maxang;
- //PSdrawRectangle(bounds.origin.x,bounds.origin.y,bounds.size.width - 2,bounds.size.height);
- NXDrawButton(&bounds, &bounds);
- PSdrawCircSlider(bounds.size.height,bounds.size.width,x,y,radius,currentang);
- [window flushWindow];
-
- /* Run modal loop until mouse up */
- looping = YES;
- while (looping) {
-
- /* Get the next mouseDragged/mouseUp event */
- theEvent=[NXApp getNextEvent:NX_MOUSEUPMASK|NX_MOUSEDRAGGEDMASK];
-
- /* Convert location to view coordinates */
- currentPoint = theEvent->location;
- [self convertPoint:¤tPoint fromView:nil];
-
- /* Handle the event */
- if (theEvent->type == NX_MOUSEDRAGGED) {
-
- // Adjust the mouseDown event's location if the Slider has been
- // scaled in either the x or y direction
-
- if (scalex > scaley ){
- newangle = angle(scalex*(currentPoint.x-(x)),currentPoint.y-(y));
- }else
- if (scalex < scaley ){
- newangle = angle(currentPoint.x-(x),scaley*(currentPoint.y-(y)));
- }else
- if (scalex = scaley ){
- newangle = angle(currentPoint.x-(x),currentPoint.y-(y));
- }
-
- if (newangle <= maxang)
- currentang = newangle;
- else
- currentang = maxang;
-
- PSdrawCircSlider(bounds.size.height,bounds.size.width,x,y,radius,currentang);
- [window flushWindow];
- if (CircFlags.continuous == 1)
- [self sendAction: _action to: _target];
- }else{
- looping = NO;
- [window flushWindow];
- [self sendAction: _action to: _target];
- }
- }
-
- /* Release the drawing context and restore the event mask */
- [self unlockFocus];
- [window setEventMask:oldMask];
- }
- return self;
- }
-
- - read:(NXTypedStream *)stream
- {
- [super read:stream];
- NXReadTypes(stream,"fffffi@:",¤tang,&maxang,&radius,&x,&y,&CircFlags,&_target,&_action);
- return(self);
- }
-
- - write:(NXTypedStream *)stream
- {
- [super write:stream];
- NXWriteTypes(stream,"fffffi@:",¤tang,&maxang,&radius,&x,&y,&CircFlags,&_target,&_action);
- return(self);
- }
-
- - (const char *)getInspectorClassName
- {
- return "CircularSliderInspector";
- }
- @end
-