libs-gui/Source/NSStepper.m

362 lines
7.2 KiB
Mathematica
Raw Normal View History

/** <title>NSStepper</title>
Copyright (C) 2001 Free Software Foundation, Inc.
Author: Pierre-Yves Rivaille <pyrivail@ens-lyon.fr>
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,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "config.h"
#include <Foundation/NSDebug.h>
#include <Foundation/NSException.h>
#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