/** NSStepper Copyright (C) 2001 Free Software Foundation, Inc. Author: Pierre-Yves Rivaille Date: August 2001 This file is part of the GNUstep GUI Library. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "config.h" #include #include #include "AppKit/NSStepper.h" #include "AppKit/NSControl.h" #include "AppKit/NSColor.h" #include "AppKit/NSEvent.h" #include "AppKit/NSWindow.h" #include "AppKit/NSApplication.h" #include "AppKit/NSStepperCell.h" // // class variables // id _nsstepperCellClass = nil; @implementation NSStepper // // Class methods // + (void) initialize { if (self == [NSStepper class]) { [self setVersion: 1]; [self setCellClass: [NSStepperCell class]]; } } // // Initializing the NSStepper Factory // + (Class) cellClass { return _nsstepperCellClass; } + (void) setCellClass: (Class)classId { _nsstepperCellClass = classId; } // // Instance methods // - (BOOL) acceptsFirstMouse: (NSEvent *)theEvent { return YES; } // // Determining the first responder // - (BOOL) becomeFirstResponder { [_cell setShowsFirstResponder: YES]; [self setNeedsDisplay: YES]; return YES; } - (BOOL) resignFirstResponder { [_cell setShowsFirstResponder: NO]; [self setNeedsDisplay: YES]; return YES; } - (void) keyDown: (NSEvent*)theEvent { } - (void) encodeWithCoder: (NSCoder *)aCoder { [super encodeWithCoder: aCoder]; } - (id) initWithCoder: (NSCoder *)aDecoder { [super initWithCoder: aDecoder]; return self; } - (double) maxValue { return [_cell maxValue]; } - (void) setMaxValue: (double)maxValue { [_cell setMaxValue: maxValue]; } - (double) minValue { return [_cell minValue]; } - (void) setMinValue: (double)minValue { [_cell setMinValue: minValue]; } - (double) increment { return [_cell increment]; } - (void) setIncrement: (double)increment { [_cell setIncrement: increment]; } - (BOOL)autorepeat { return [_cell autorepeat]; } - (void)setAutorepeat: (BOOL)autorepeat { [_cell setAutorepeat: autorepeat]; } - (BOOL)valueWraps { return [_cell valueWraps]; } - (void)setValueWraps: (BOOL)valueWraps { [_cell setValueWraps: valueWraps]; } - (void) mouseDown: (NSEvent *)event { NSPoint point = [event locationInWindow]; NSRect upRect; NSRect downRect; NSRect rect; BOOL isDirectionUp; BOOL autorepeat = [_cell autorepeat]; if([_cell isEnabled] == NO) return; if([event type] != NSLeftMouseDown) return; upRect = [_cell upButtonRectWithFrame: _bounds]; downRect = [_cell downButtonRectWithFrame: _bounds]; point = [self convertPoint: point fromView: nil]; if (NSMouseInRect(point, upRect, NO)) { isDirectionUp = YES; rect = upRect; } else if (NSMouseInRect(point, downRect, NO)) { isDirectionUp = NO; rect = downRect; } else { return; } [self lockFocus]; { BOOL overButton = YES; int ignore = 3; unsigned int eventMask = NSLeftMouseUpMask | NSLeftMouseDraggedMask | NSPeriodicMask; NSDate *farAway = [NSDate distantFuture]; [_window flushWindow]; [_cell highlight: YES upButton: isDirectionUp withFrame: _bounds inView: self]; [_window _captureMouse: self]; if (autorepeat) { [NSEvent startPeriodicEventsAfterDelay: 0.5 withPeriod: 0.025]; if (isDirectionUp) [self _increment]; else [self _decrement]; [_cell drawWithFrame:_bounds inView:self]; [_window flushWindow]; } else [_window flushWindow]; event = [NSApp nextEventMatchingMask: eventMask untilDate: farAway inMode: NSEventTrackingRunLoopMode dequeue: YES]; while([event type] != NSLeftMouseUp) { if ([event type] == NSPeriodic) { ignore ++; if (ignore == 4) ignore = 0; if (ignore == 0) { if (isDirectionUp) [self _increment]; else [self _decrement]; [_cell drawWithFrame:_bounds inView:self]; [_window flushWindow]; } } else if (NSMouseInRect(point, rect, NO) != overButton) { overButton = !overButton; if (overButton && autorepeat) { [NSEvent startPeriodicEventsAfterDelay: 0.5 withPeriod: 0.025]; ignore = 3; } else { [NSEvent stopPeriodicEvents]; } [_cell highlight: overButton upButton: isDirectionUp withFrame: _bounds inView: self]; [_window flushWindow]; } event = [NSApp nextEventMatchingMask: eventMask untilDate: farAway inMode: NSEventTrackingRunLoopMode dequeue: YES]; point = [self convertPoint: [event locationInWindow] fromView: nil]; } if (overButton && autorepeat) [NSEvent stopPeriodicEvents]; if (overButton && !autorepeat) { if (isDirectionUp) [self _increment]; else [self _decrement]; [_cell drawWithFrame:_bounds inView:self]; } [_cell highlight: NO upButton: isDirectionUp withFrame: _bounds inView: self]; [_window flushWindow]; [_window _releaseMouse: self]; } [self unlockFocus]; } - (void)_increment { double newValue; double maxValue = [_cell maxValue]; double minValue = [_cell minValue]; double increment = [_cell increment]; newValue = [_cell doubleValue] + increment; if ([_cell valueWraps]) { if (newValue > maxValue) [_cell setDoubleValue: newValue - maxValue + minValue - 1]; else if (newValue < minValue) [_cell setDoubleValue: newValue + maxValue - minValue + 1]; else [_cell setDoubleValue: newValue]; } else { if (newValue > maxValue) [_cell setDoubleValue: maxValue]; else if (newValue < minValue) [_cell setDoubleValue: minValue]; else [_cell setDoubleValue: newValue]; } [self sendAction: [self action] to: [self target]]; } - (void)_decrement { double newValue; double maxValue = [_cell maxValue]; double minValue = [_cell minValue]; double increment = [_cell increment]; newValue = [_cell doubleValue] - increment; if ([_cell valueWraps]) { if (newValue > maxValue) [_cell setDoubleValue: newValue - maxValue + minValue - 1]; else if (newValue < minValue) [_cell setDoubleValue: newValue + maxValue - minValue + 1]; else [_cell setDoubleValue: newValue]; } else { if (newValue > maxValue) [_cell setDoubleValue: maxValue]; else if (newValue < minValue) [_cell setDoubleValue: minValue]; else [_cell setDoubleValue: newValue]; } [self sendAction: [self action] to: [self target]]; } @end