/* NSStepper.m Text field control and cell classes Author: Nikolaus Schaller Date: April 2006 This file is part of the mySTEP Library and is provided under the terms of the GNU Library General Public License. */ #import #import #import #import #import #import #import #import "NSAppKitPrivate.h" @implementation NSStepperCell // draw two vertical arrow triangle buttons // enable/disable if stuck at max/min // update [self doubleValue] by increment; - (id) init; { if((self=[super init])) { _maxValue=59.0; _increment=1.0; _autorepeat=YES; _valueWraps=YES; } return self; } - (id) copyWithZone:(NSZone *) zone; { NSStepperCell *c = [super copyWithZone:zone]; // copy values return c; } - (void) dealloc; { [_upCell release]; [_downCell release]; [super dealloc]; } - (NSSize) cellSize; { // sum up all widths and use default height for controlSize NIMP; return NSZeroSize; } - (void) drawInteriorWithFrame:(NSRect) cellFrame inView:(NSView*) controlView { NSRect upper, lower; #if 0 NSLog(@"drawInteriorWithFrame %@", self); #endif NSDivideRect(cellFrame, &upper, &lower, cellFrame.size.height/2.0, NSMaxYEdge); // split by 2 if(!_downCell) { // allocate button cells int i; for(i=0; i<2; i++) { NSButtonCell *c=[[NSButtonCell alloc] init]; [c setImage:[NSImage imageNamed:i==0?@"GSArrowUp":@"GSArrowDown"]]; [c setAlternateImage:[NSImage imageNamed:i==0?@"GSArrowUpH":@"GSArrowDownH"]]; [c setImagePosition:NSImageOnly]; [c setTarget:self]; [c setAction:i==0?@selector(_increment):@selector(_decrement)]; [c setBezelStyle:NSRegularSquareBezelStyle]; [c setButtonType:NSMomentaryChangeButton]; // ??? [c setPeriodicDelay:0.5 interval:0.1]; if(i==0) _upCell=c; else _downCell=c; } } [_upCell drawInteriorWithFrame:upper inView:controlView]; [_downCell drawInteriorWithFrame:lower inView:controlView]; } /*- (void) drawWithFrame:(NSRect)frame inView:(NSView*)controlView { // we don't have this method... } */ - (BOOL) trackMouse:(NSEvent *)event inRect:(NSRect)cellFrame ofView:(NSView *)controlView untilMouseUp:(BOOL)untilMouseUp { // check if we should forward to subcell NSPoint loc=[event locationInWindow]; loc = [controlView convertPoint:loc fromView:nil]; // convert to controlView's coordinates NSLog(@"NSStepperCell trackMouse:%@ inRect:%@", NSStringFromPoint(loc), NSStringFromRect(cellFrame)); // FIXME: do we need to know if [controlView isFlipped]? if(loc.y-cellFrame.origin.y > cellFrame.size.height/2.0) return [_upCell trackMouse:event inRect:cellFrame ofView:controlView untilMouseUp:untilMouseUp]; else return [_downCell trackMouse:event inRect:cellFrame ofView:controlView untilMouseUp:untilMouseUp]; } - (BOOL) autorepeat; { return _autorepeat; } // after 0.5 seconds with 0.1 seconds distance - (double) increment; { return _increment; } - (double) maxValue; { return _maxValue; } - (double) minValue; { return _minValue; } - (void) setAutorepeat:(BOOL) flag; { _autorepeat=flag; } - (void) setIncrement:(double) val; { _increment=val; } - (void) setMaxValue:(double) val; { _maxValue=val; } - (void) setMinValue:(double) val; { _minValue=val; } - (void) setValueWraps:(BOOL) flag; { _valueWraps=flag; } - (BOOL) valueWraps; { return _valueWraps; } - (float) floatValue; { return _value; } - (double) doubleValue; { return _value; } - (void) setFloatValue:(float) val; { _value=val; } - (void) setDoubleValue:(double) val; { _value=val; } - (IBAction ) _increment:(id) sender; { [self willChangeValueForKey:@"Value"]; _value+=_increment; if(_value > _maxValue) _value=_valueWraps?_minValue:_maxValue; [self didChangeValueForKey:@"Value"]; } - (IBAction ) _decrement:(id) sender; { [self willChangeValueForKey:@"Value"]; _value-=_increment; if(_value < _minValue) _value=_valueWraps?_maxValue:_minValue; [self didChangeValueForKey:@"Value"]; } - (void) encodeWithCoder:(NSCoder *) aCoder { [super encodeWithCoder:aCoder]; NIMP; } - (id) initWithCoder:(NSCoder *) aDecoder { self=[super initWithCoder:aDecoder]; if(![aDecoder allowsKeyedCoding]) { [self release]; return nil; } _autorepeat=[aDecoder decodeBoolForKey:@"NSAutorepeat"]; _valueWraps=[aDecoder decodeBoolForKey:@"NSValueWraps"]; _increment=[aDecoder decodeDoubleForKey:@"NSIncrement"]; _minValue=[aDecoder decodeDoubleForKey:@"NSMinValue"]; _maxValue=[aDecoder decodeDoubleForKey:@"NSMaxValue"]; _value=[aDecoder decodeDoubleForKey:@"NSValue"]; #if 0 NSLog(@"%@ initWithCoder:%@", self, aDecoder); #endif return self; } @end @implementation NSStepper - (BOOL) autorepeat; { return [_cell autorepeat]; } - (double) increment; { return [_cell increment]; } - (double) maxValue; { return [_cell maxValue]; } - (double) minValue; { return [_cell minValue]; } - (void) setAutorepeat:(BOOL) flag; { [_cell setAutorepeat:flag]; } - (void) setIncrement:(double) val; { [_cell setIncrement:val]; } - (void) setMaxValue:(double) val; { [_cell setMaxValue:val]; } - (void) setMinValue:(double) val; { [_cell setMinValue:val]; } - (void) setValueWraps:(BOOL) flag; { [_cell setValueWraps:flag]; } - (BOOL) valueWraps; { return [_cell valueWraps]; } @end