1997-08-05 21:50:10 +00:00
|
|
|
/*
|
1996-05-30 20:03:15 +00:00
|
|
|
NSScroller.m
|
|
|
|
|
|
|
|
Copyright (C) 1996 Free Software Foundation, Inc.
|
|
|
|
|
1997-08-05 21:50:10 +00:00
|
|
|
Author: Ovidiu Predescu <ovidiu@net-community.com>
|
|
|
|
A completely rewritten version of the original source by Scott Christley.
|
|
|
|
Date: July 1997
|
1998-08-30 16:06:47 +00:00
|
|
|
Author: Felipe A. Rodriguez <far@ix.netcom.com>
|
|
|
|
Date: August 1998
|
1999-03-14 10:58:59 +00:00
|
|
|
Author: Richard frith-Macdonald <richard@brainstorm.co.uk>
|
|
|
|
Date: Mar 1999 - Use flipped views and make conform to spec
|
1999-02-03 21:53:29 +00:00
|
|
|
|
1996-05-30 20:03:15 +00:00
|
|
|
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.
|
1999-02-03 21:53:29 +00:00
|
|
|
|
1996-05-30 20:03:15 +00:00
|
|
|
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
|
1997-08-05 21:50:10 +00:00
|
|
|
License along with this library; if not, write to the Free
|
|
|
|
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
*/
|
|
|
|
|
1997-09-23 22:43:24 +00:00
|
|
|
#include <gnustep/gui/config.h>
|
1998-12-09 01:26:37 +00:00
|
|
|
#include <math.h>
|
|
|
|
|
1997-08-05 21:50:10 +00:00
|
|
|
#include <Foundation/NSDate.h>
|
|
|
|
#include <Foundation/NSRunLoop.h>
|
1996-05-30 20:03:15 +00:00
|
|
|
|
1997-02-18 00:29:25 +00:00
|
|
|
#include <AppKit/NSScroller.h>
|
1998-10-15 12:04:53 +00:00
|
|
|
#include <AppKit/NSScrollView.h>
|
1997-02-18 00:29:25 +00:00
|
|
|
#include <AppKit/NSWindow.h>
|
1997-08-05 21:50:10 +00:00
|
|
|
#include <AppKit/NSButtonCell.h>
|
1997-03-05 01:11:17 +00:00
|
|
|
#include <AppKit/NSApplication.h>
|
|
|
|
#include <AppKit/NSImage.h>
|
1999-02-15 19:35:02 +00:00
|
|
|
#include <AppKit/NSColor.h>
|
|
|
|
#include <AppKit/NSGraphics.h>
|
1997-03-05 01:11:17 +00:00
|
|
|
|
1996-05-30 20:03:15 +00:00
|
|
|
|
1998-11-25 17:16:48 +00:00
|
|
|
@implementation NSScroller
|
1997-03-05 01:11:17 +00:00
|
|
|
|
1999-06-06 08:19:19 +00:00
|
|
|
/*
|
|
|
|
* Class variables
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* button cells used by scroller instances to draw scroller buttons and knob. */
|
|
|
|
static NSButtonCell* upCell = nil;
|
|
|
|
static NSButtonCell* downCell = nil;
|
|
|
|
static NSButtonCell* leftCell = nil;
|
|
|
|
static NSButtonCell* rightCell = nil;
|
1997-08-05 21:50:10 +00:00
|
|
|
static NSButtonCell* knobCell = nil;
|
1997-03-05 01:11:17 +00:00
|
|
|
|
1999-03-16 16:38:26 +00:00
|
|
|
static const float scrollerWidth = 18;
|
1998-11-25 17:16:48 +00:00
|
|
|
static const float buttonsWidth = 16;
|
|
|
|
|
1999-02-03 21:53:29 +00:00
|
|
|
static float halfKnobRectHeight;
|
1998-11-25 17:16:48 +00:00
|
|
|
static float slotOriginPlusKnobHeight;
|
|
|
|
static float slotOriginPlusSlotHeightMinusKnobHeight;
|
|
|
|
static float slotHeightMinusKnobHeight;
|
|
|
|
static float halfKnobRectWidth;
|
|
|
|
static float slotOriginPlusKnobWidth;
|
|
|
|
static float slotOriginPlusSlotWidthMinusHalfKnobWidth;
|
|
|
|
static float slotWidthMinusKnobWidth;
|
|
|
|
static NSRect slotRect = {{0,0},{0,0}};
|
|
|
|
static BOOL preCalcValues = NO;
|
|
|
|
|
1999-06-06 08:19:19 +00:00
|
|
|
/*
|
|
|
|
* Class methods
|
|
|
|
*/
|
1999-02-03 21:53:29 +00:00
|
|
|
+ (void) initialize
|
|
|
|
{
|
|
|
|
if (self == [NSScroller class])
|
|
|
|
[self setVersion: 1];
|
|
|
|
}
|
1998-12-09 01:26:37 +00:00
|
|
|
|
1999-02-03 21:53:29 +00:00
|
|
|
+ (float) scrollerWidth
|
|
|
|
{
|
|
|
|
return scrollerWidth;
|
|
|
|
}
|
1998-12-09 01:26:37 +00:00
|
|
|
|
1999-03-14 10:58:59 +00:00
|
|
|
- (BOOL) isFlipped
|
|
|
|
{
|
|
|
|
return YES;
|
|
|
|
}
|
|
|
|
|
1999-03-24 11:31:06 +00:00
|
|
|
- (BOOL) acceptsFirstMouse: (NSEvent *)theEvent
|
|
|
|
{
|
|
|
|
return YES;
|
|
|
|
}
|
|
|
|
|
1999-02-03 21:53:29 +00:00
|
|
|
- (NSScrollArrowPosition) arrowsPosition
|
|
|
|
{
|
|
|
|
return _arrowsPosition;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSUsableScrollerParts) usableParts
|
|
|
|
{
|
|
|
|
return _usableParts;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (float) knobProportion
|
|
|
|
{
|
|
|
|
return _knobProportion;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSScrollerPart) hitPart
|
|
|
|
{
|
|
|
|
return _hitPart;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (float) floatValue
|
|
|
|
{
|
|
|
|
return _floatValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) setAction: (SEL)action
|
|
|
|
{
|
|
|
|
_action = action;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (SEL) action
|
|
|
|
{
|
|
|
|
return _action;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) setTarget: (id)target
|
|
|
|
{
|
|
|
|
ASSIGN(_target, target);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (id) target
|
|
|
|
{
|
|
|
|
return _target;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) encodeWithCoder: (NSCoder*)aCoder
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
- (id) initWithCoder: (NSCoder*)aDecoder
|
|
|
|
{
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL) isOpaque
|
|
|
|
{
|
|
|
|
return YES;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (id) initWithFrame: (NSRect)frameRect
|
|
|
|
{
|
1999-06-06 08:19:19 +00:00
|
|
|
/*
|
|
|
|
* determine the orientation of the scroller and adjust it's size accordingly
|
|
|
|
*/
|
1999-02-03 21:53:29 +00:00
|
|
|
if (frameRect.size.width > frameRect.size.height)
|
|
|
|
{
|
|
|
|
_isHorizontal = YES;
|
|
|
|
frameRect.size.height = [isa scrollerWidth];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
_isHorizontal = NO;
|
|
|
|
frameRect.size.width = [isa scrollerWidth];
|
|
|
|
}
|
|
|
|
|
|
|
|
[super initWithFrame: frameRect];
|
|
|
|
|
|
|
|
if (_isHorizontal)
|
1999-03-14 10:58:59 +00:00
|
|
|
{
|
|
|
|
_arrowsPosition = NSScrollerArrowsMinEnd;
|
|
|
|
_floatValue = 0.0;
|
|
|
|
}
|
1999-02-03 21:53:29 +00:00
|
|
|
else
|
1999-03-14 10:58:59 +00:00
|
|
|
{
|
|
|
|
_arrowsPosition = NSScrollerArrowsMaxEnd;
|
|
|
|
_floatValue = 1.0;
|
|
|
|
}
|
1999-02-03 21:53:29 +00:00
|
|
|
|
|
|
|
_hitPart = NSScrollerNoPart;
|
|
|
|
[self drawParts];
|
|
|
|
[self setEnabled: NO];
|
|
|
|
[self checkSpaceForParts];
|
|
|
|
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (id) init
|
|
|
|
{
|
|
|
|
return [self initWithFrame: NSZeroRect];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) drawParts
|
|
|
|
{
|
1999-06-06 08:19:19 +00:00
|
|
|
/*
|
|
|
|
* Create the class variable button cells if they do not yet exist.
|
|
|
|
*/
|
1999-02-03 21:53:29 +00:00
|
|
|
if (knobCell)
|
|
|
|
return;
|
|
|
|
|
|
|
|
upCell = [NSButtonCell new];
|
|
|
|
[upCell setHighlightsBy: NSChangeBackgroundCellMask|NSContentsCellMask];
|
|
|
|
[upCell setImage: [NSImage imageNamed: @"common_ArrowUp"]];
|
|
|
|
[upCell setAlternateImage: [NSImage imageNamed: @"common_ArrowUpH"]];
|
|
|
|
[upCell setImagePosition: NSImageOnly];
|
|
|
|
[upCell setContinuous: YES];
|
|
|
|
[upCell setPeriodicDelay: 0.05 interval: 0.05];
|
|
|
|
|
|
|
|
downCell = [NSButtonCell new];
|
|
|
|
[downCell setHighlightsBy: NSChangeBackgroundCellMask|NSContentsCellMask];
|
|
|
|
[downCell setImage: [NSImage imageNamed: @"common_ArrowDown"]];
|
|
|
|
[downCell setAlternateImage: [NSImage imageNamed: @"common_ArrowDownH"]];
|
|
|
|
[downCell setImagePosition: NSImageOnly];
|
|
|
|
[downCell setContinuous: YES];
|
|
|
|
[downCell setPeriodicDelay: 0.05 interval: 0.05];
|
|
|
|
|
|
|
|
leftCell = [NSButtonCell new];
|
|
|
|
[leftCell setHighlightsBy: NSChangeBackgroundCellMask|NSContentsCellMask];
|
|
|
|
[leftCell setImage: [NSImage imageNamed: @"common_ArrowLeft"]];
|
|
|
|
[leftCell setAlternateImage: [NSImage imageNamed: @"common_ArrowLeftH"]];
|
|
|
|
[leftCell setImagePosition: NSImageOnly];
|
|
|
|
[leftCell setContinuous: YES];
|
|
|
|
[leftCell setPeriodicDelay: 0.05 interval: 0.05];
|
|
|
|
|
|
|
|
rightCell = [NSButtonCell new];
|
|
|
|
[rightCell setHighlightsBy: NSChangeBackgroundCellMask|NSContentsCellMask];
|
|
|
|
[rightCell setImage: [NSImage imageNamed: @"common_ArrowRight"]];
|
|
|
|
[rightCell setAlternateImage: [NSImage imageNamed: @"common_ArrowRightH"]];
|
|
|
|
[rightCell setImagePosition: NSImageOnly];
|
|
|
|
[rightCell setContinuous: YES];
|
|
|
|
[rightCell setPeriodicDelay: 0.05 interval: 0.05];
|
|
|
|
|
|
|
|
knobCell = [NSButtonCell new];
|
|
|
|
[knobCell setButtonType: NSMomentaryChangeButton];
|
|
|
|
[knobCell setImage: [NSImage imageNamed: @"common_Dimple"]];
|
|
|
|
[knobCell setImagePosition: NSImageOnly];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) _setTargetAndActionToCells
|
|
|
|
{
|
|
|
|
[upCell setTarget: _target];
|
|
|
|
[upCell setAction: _action];
|
|
|
|
|
|
|
|
[downCell setTarget: _target];
|
|
|
|
[downCell setAction: _action];
|
|
|
|
|
|
|
|
[leftCell setTarget: _target];
|
|
|
|
[leftCell setAction: _action];
|
|
|
|
|
|
|
|
[rightCell setTarget: _target];
|
|
|
|
[rightCell setAction: _action];
|
|
|
|
|
|
|
|
[knobCell setTarget: _target];
|
|
|
|
[knobCell setAction: _action];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) checkSpaceForParts
|
|
|
|
{
|
1999-03-14 10:58:59 +00:00
|
|
|
NSSize frameSize = [self frame].size;
|
|
|
|
float size = (_isHorizontal ? frameSize.width : frameSize.height);
|
|
|
|
float scrollerWidth = [isa scrollerWidth];
|
1999-02-03 21:53:29 +00:00
|
|
|
|
1999-03-14 10:58:59 +00:00
|
|
|
if (_arrowsPosition == NSScrollerArrowsNone)
|
|
|
|
{
|
1999-03-16 16:38:26 +00:00
|
|
|
if (size >= scrollerWidth + 2)
|
1999-03-14 10:58:59 +00:00
|
|
|
_usableParts = NSAllScrollerParts;
|
|
|
|
else
|
|
|
|
_usableParts = NSNoScrollerParts;
|
|
|
|
}
|
1999-02-03 21:53:29 +00:00
|
|
|
else
|
1999-03-14 10:58:59 +00:00
|
|
|
{
|
1999-03-16 16:38:26 +00:00
|
|
|
if (size >= 3 * scrollerWidth + 4)
|
1999-03-14 10:58:59 +00:00
|
|
|
_usableParts = NSAllScrollerParts;
|
1999-03-16 16:38:26 +00:00
|
|
|
else if (size >= 2 * scrollerWidth + 3)
|
1999-03-14 10:58:59 +00:00
|
|
|
_usableParts = NSOnlyScrollerArrows;
|
|
|
|
else
|
|
|
|
_usableParts = NSNoScrollerParts;
|
|
|
|
}
|
1999-02-03 21:53:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void) setEnabled: (BOOL)flag
|
|
|
|
{
|
|
|
|
if (_isEnabled == flag)
|
|
|
|
return;
|
|
|
|
|
|
|
|
_isEnabled = flag;
|
|
|
|
[self setNeedsDisplay: YES];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) setArrowsPosition: (NSScrollArrowPosition)where
|
|
|
|
{
|
|
|
|
if (_arrowsPosition == where)
|
|
|
|
return;
|
|
|
|
|
|
|
|
_arrowsPosition = where;
|
|
|
|
[self setNeedsDisplay: YES];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) setFloatValue: (float)aFloat
|
|
|
|
{
|
|
|
|
if (aFloat < 0)
|
|
|
|
_floatValue = 0;
|
|
|
|
else if (aFloat > 1)
|
|
|
|
_floatValue = 1;
|
|
|
|
else
|
|
|
|
_floatValue = aFloat;
|
|
|
|
|
|
|
|
[self setNeedsDisplayInRect: [self rectForPart: NSScrollerKnobSlot]];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) setFloatValue: (float)aFloat knobProportion: (float)ratio
|
|
|
|
{
|
|
|
|
if (ratio < 0)
|
|
|
|
_knobProportion = 0;
|
|
|
|
else if (ratio > 1)
|
|
|
|
_knobProportion = 1;
|
|
|
|
else
|
|
|
|
_knobProportion = ratio;
|
|
|
|
|
|
|
|
[self setFloatValue: aFloat];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) setFrame: (NSRect)frameRect
|
|
|
|
{
|
1999-06-06 08:19:19 +00:00
|
|
|
/*
|
|
|
|
* determine the orientation of the scroller and adjust it's size accordingly
|
|
|
|
*/
|
1999-02-03 21:53:29 +00:00
|
|
|
if (frameRect.size.width > frameRect.size.height)
|
|
|
|
{
|
|
|
|
_isHorizontal = YES;
|
|
|
|
frameRect.size.height = [isa scrollerWidth];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
_isHorizontal = NO;
|
|
|
|
frameRect.size.width = [isa scrollerWidth];
|
|
|
|
}
|
|
|
|
|
|
|
|
[super setFrame: frameRect];
|
|
|
|
|
|
|
|
if (_isHorizontal)
|
|
|
|
_arrowsPosition = NSScrollerArrowsMinEnd;
|
|
|
|
else
|
|
|
|
_arrowsPosition = NSScrollerArrowsMaxEnd;
|
|
|
|
|
|
|
|
_hitPart = NSScrollerNoPart;
|
|
|
|
[self checkSpaceForParts];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) setFrameSize: (NSSize)size
|
|
|
|
{
|
|
|
|
[super setFrameSize: size];
|
|
|
|
[self checkSpaceForParts];
|
|
|
|
[self setNeedsDisplay: YES];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSScrollerPart)testPart: (NSPoint)thePoint
|
|
|
|
{
|
1999-06-06 08:19:19 +00:00
|
|
|
/*
|
|
|
|
* return what part of the scroller the mouse hit
|
|
|
|
*/
|
1999-02-03 21:53:29 +00:00
|
|
|
NSRect rect;
|
|
|
|
|
1999-03-16 16:38:26 +00:00
|
|
|
if (thePoint.x <= 0 || thePoint.x >= frame.size.width
|
|
|
|
|| thePoint.y <= 0 || thePoint.y >= frame.size.height)
|
1999-02-03 21:53:29 +00:00
|
|
|
return NSScrollerNoPart;
|
|
|
|
|
|
|
|
rect = [self rectForPart: NSScrollerDecrementLine];
|
|
|
|
if ([self mouse: thePoint inRect: rect])
|
|
|
|
return NSScrollerDecrementLine;
|
|
|
|
|
|
|
|
rect = [self rectForPart: NSScrollerIncrementLine];
|
|
|
|
if ([self mouse: thePoint inRect: rect])
|
|
|
|
return NSScrollerIncrementLine;
|
|
|
|
|
|
|
|
rect = [self rectForPart: NSScrollerKnob];
|
|
|
|
if ([self mouse: thePoint inRect: rect])
|
|
|
|
return NSScrollerKnob;
|
|
|
|
|
|
|
|
rect = [self rectForPart: NSScrollerDecrementPage];
|
|
|
|
if ([self mouse: thePoint inRect: rect])
|
|
|
|
return NSScrollerDecrementPage;
|
|
|
|
|
|
|
|
rect = [self rectForPart: NSScrollerIncrementPage];
|
|
|
|
if ([self mouse: thePoint inRect: rect])
|
|
|
|
return NSScrollerIncrementPage;
|
|
|
|
|
1999-03-14 10:58:59 +00:00
|
|
|
rect = [self rectForPart: NSScrollerKnobSlot];
|
|
|
|
if ([self mouse: thePoint inRect: rect])
|
|
|
|
return NSScrollerKnobSlot;
|
|
|
|
|
1999-02-03 21:53:29 +00:00
|
|
|
return NSScrollerNoPart;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (float) _floatValueForMousePoint: (NSPoint)point
|
|
|
|
{
|
|
|
|
NSRect knobRect = [self rectForPart: NSScrollerKnob];
|
|
|
|
NSRect slotRect = [self rectForPart: NSScrollerKnobSlot];
|
|
|
|
float floatValue = 0;
|
|
|
|
float position;
|
|
|
|
|
1999-06-06 08:19:19 +00:00
|
|
|
/*
|
|
|
|
* Adjust point to lie within the knob slot
|
|
|
|
*/
|
1999-02-03 21:53:29 +00:00
|
|
|
if (_isHorizontal)
|
|
|
|
{
|
|
|
|
float halfKnobRectWidth = knobRect.size.width / 2;
|
|
|
|
|
|
|
|
if (point.x < slotRect.origin.x + halfKnobRectWidth)
|
|
|
|
position = slotRect.origin.x + halfKnobRectWidth;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (point.x > slotRect.origin.x + slotRect.size.width -
|
1998-11-25 17:16:48 +00:00
|
|
|
halfKnobRectWidth)
|
1999-02-03 21:53:29 +00:00
|
|
|
position = slotRect.origin.x + slotRect.size.width -
|
1998-11-25 17:16:48 +00:00
|
|
|
halfKnobRectWidth;
|
1999-02-03 21:53:29 +00:00
|
|
|
else
|
|
|
|
position = point.x;
|
|
|
|
}
|
1999-06-06 08:19:19 +00:00
|
|
|
/*
|
|
|
|
* Compute float value given the knob size
|
|
|
|
*/
|
1999-02-03 21:53:29 +00:00
|
|
|
floatValue = (position - (slotRect.origin.x + halfKnobRectWidth))
|
|
|
|
/ (slotRect.size.width - knobRect.size.width);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
float halfKnobRectHeight = knobRect.size.height / 2;
|
|
|
|
|
|
|
|
if (point.y < slotRect.origin.y + halfKnobRectHeight)
|
|
|
|
position = slotRect.origin.y + halfKnobRectHeight;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (point.y > slotRect.origin.y + slotRect.size.height -
|
|
|
|
halfKnobRectHeight)
|
|
|
|
position = slotRect.origin.y + slotRect.size.height -
|
|
|
|
halfKnobRectHeight;
|
|
|
|
else
|
|
|
|
position = point.y;
|
|
|
|
}
|
1999-06-06 08:19:19 +00:00
|
|
|
/*
|
|
|
|
* Compute float value given the knob size
|
|
|
|
*/
|
1999-02-03 21:53:29 +00:00
|
|
|
floatValue = (position - (slotRect.origin.y + halfKnobRectHeight)) /
|
|
|
|
(slotRect.size.height - knobRect.size.height);
|
|
|
|
}
|
|
|
|
|
|
|
|
return floatValue;
|
|
|
|
}
|
1998-11-25 17:16:48 +00:00
|
|
|
|
1999-02-03 21:53:29 +00:00
|
|
|
- (void) _preCalcParts
|
|
|
|
{
|
|
|
|
NSRect knobRect = [self rectForPart: NSScrollerKnob];
|
|
|
|
|
|
|
|
slotRect = [self rectForPart: NSScrollerKnobSlot];
|
|
|
|
halfKnobRectWidth = knobRect.size.width / 2;
|
|
|
|
slotOriginPlusKnobWidth = slotRect.origin.x + halfKnobRectWidth;
|
|
|
|
slotOriginPlusSlotWidthMinusHalfKnobWidth = slotRect.origin.x +
|
|
|
|
slotRect.size.width - halfKnobRectWidth;
|
|
|
|
slotWidthMinusKnobWidth = slotRect.size.width - knobRect.size.width;
|
|
|
|
|
|
|
|
halfKnobRectHeight = knobRect.size.height / 2;
|
|
|
|
slotOriginPlusKnobHeight = slotRect.origin.y + halfKnobRectHeight;
|
|
|
|
slotOriginPlusSlotHeightMinusKnobHeight = slotRect.origin.y +
|
|
|
|
slotRect.size.height - halfKnobRectHeight;
|
|
|
|
slotHeightMinusKnobHeight = slotRect.size.height - knobRect.size.height;
|
|
|
|
}
|
1998-11-25 17:16:48 +00:00
|
|
|
|
1999-02-03 21:53:29 +00:00
|
|
|
- (float) _floatValueForMousePointFromPreCalc: (NSPoint)point
|
|
|
|
{
|
|
|
|
float floatValue = 0;
|
|
|
|
float position;
|
|
|
|
|
|
|
|
if (_isHorizontal)
|
|
|
|
{
|
|
|
|
if (point.x < slotOriginPlusKnobWidth)
|
|
|
|
position = slotOriginPlusKnobWidth;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (point.x > slotOriginPlusSlotWidthMinusHalfKnobWidth)
|
|
|
|
position = slotOriginPlusSlotWidthMinusHalfKnobWidth;
|
|
|
|
else
|
|
|
|
position = point.x;
|
|
|
|
}
|
|
|
|
floatValue = (position - slotOriginPlusKnobWidth) /
|
|
|
|
slotWidthMinusKnobWidth;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (point.y < slotOriginPlusKnobHeight)
|
|
|
|
position = slotOriginPlusKnobHeight;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (point.y > slotOriginPlusSlotHeightMinusKnobHeight)
|
|
|
|
position = slotOriginPlusSlotHeightMinusKnobHeight;
|
|
|
|
else
|
|
|
|
position = point.y;
|
|
|
|
}
|
|
|
|
|
|
|
|
floatValue = (position - slotOriginPlusKnobHeight) /
|
|
|
|
slotHeightMinusKnobHeight;
|
|
|
|
}
|
|
|
|
|
|
|
|
return floatValue;
|
1997-03-05 01:11:17 +00:00
|
|
|
}
|
|
|
|
|
1999-02-03 21:53:29 +00:00
|
|
|
- (void) mouseDown: (NSEvent*)theEvent
|
1997-03-05 01:11:17 +00:00
|
|
|
{
|
1999-02-03 21:53:29 +00:00
|
|
|
NSPoint location = [self convertPoint: [theEvent locationInWindow]
|
|
|
|
fromView: nil];
|
|
|
|
|
|
|
|
_hitPart = [self testPart: location];
|
|
|
|
[self _setTargetAndActionToCells];
|
|
|
|
|
|
|
|
switch (_hitPart)
|
|
|
|
{
|
|
|
|
case NSScrollerIncrementLine:
|
|
|
|
case NSScrollerDecrementLine:
|
1999-06-11 07:22:37 +00:00
|
|
|
/*
|
|
|
|
* A hit on a scroller button should be a page meovement
|
|
|
|
* if the alt key is pressed.
|
|
|
|
*/
|
|
|
|
if ([theEvent modifierFlags] & NSAlternateKeyMask)
|
|
|
|
{
|
|
|
|
if (_hitPart == NSScrollerIncrementLine)
|
|
|
|
{
|
|
|
|
_hitPart = NSScrollerIncrementPage;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
_hitPart = NSScrollerDecrementPage;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* Fall through to next case */
|
|
|
|
|
1999-02-03 21:53:29 +00:00
|
|
|
case NSScrollerIncrementPage:
|
|
|
|
case NSScrollerDecrementPage:
|
|
|
|
[self trackScrollButtons: theEvent];
|
|
|
|
break;
|
|
|
|
|
|
|
|
case NSScrollerKnob:
|
|
|
|
[self trackKnob: theEvent];
|
|
|
|
break;
|
|
|
|
|
|
|
|
case NSScrollerKnobSlot:
|
|
|
|
{
|
|
|
|
float floatValue = [self _floatValueForMousePoint: location];
|
|
|
|
|
|
|
|
[self setFloatValue: floatValue];
|
|
|
|
[self sendAction: _action to: _target];
|
|
|
|
[self trackKnob: theEvent];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case NSScrollerNoPart:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
_hitPart = NSScrollerNoPart;
|
|
|
|
}
|
1998-11-25 17:16:48 +00:00
|
|
|
|
1999-02-05 06:44:40 +00:00
|
|
|
- (void) trackKnob: (NSEvent*)theEvent
|
1999-02-03 21:53:29 +00:00
|
|
|
{
|
|
|
|
unsigned int eventMask = NSLeftMouseDownMask | NSLeftMouseUpMask
|
|
|
|
| NSLeftMouseDraggedMask | NSMouseMovedMask
|
|
|
|
| NSPeriodicMask;
|
1999-06-06 08:19:19 +00:00
|
|
|
NSPoint point;
|
|
|
|
NSPoint apoint;
|
|
|
|
float oldFloatValue = _floatValue;
|
|
|
|
float floatValue;
|
|
|
|
float xoffset = 0;
|
|
|
|
float yoffset = 0;
|
|
|
|
NSDate *theDistantFuture = [NSDate distantFuture];
|
|
|
|
NSEventType eventType;
|
|
|
|
NSRect knobRect = {{0,0},{0,0}};
|
|
|
|
unsigned periodCount = 0;
|
|
|
|
unsigned flags = [theEvent modifierFlags];
|
|
|
|
BOOL firstTime = YES;
|
|
|
|
|
|
|
|
[self _preCalcParts];
|
1999-02-03 21:53:29 +00:00
|
|
|
preCalcValues = YES;
|
1999-02-19 20:19:58 +00:00
|
|
|
|
1999-02-05 06:44:40 +00:00
|
|
|
knobRect = [self rectForPart: NSScrollerKnob];
|
|
|
|
|
|
|
|
if (_hitPart == NSScrollerKnob)
|
|
|
|
{
|
|
|
|
apoint = [theEvent locationInWindow];
|
|
|
|
point = [self convertPoint: apoint fromView: nil];
|
|
|
|
if (_isHorizontal)
|
|
|
|
{
|
|
|
|
if (point.x != knobRect.origin.x + knobRect.size.width/2)
|
|
|
|
{
|
|
|
|
xoffset = knobRect.origin.x + knobRect.size.width/2 - point.x;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (point.y != knobRect.origin.y + knobRect.size.height/2)
|
|
|
|
{
|
|
|
|
yoffset = knobRect.origin.y + knobRect.size.height/2 - point.y;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
1999-02-03 21:53:29 +00:00
|
|
|
|
|
|
|
_hitPart = NSScrollerKnob;
|
1999-06-06 08:19:19 +00:00
|
|
|
/*
|
|
|
|
* set periodic events rate to achieve max of ~30fps
|
|
|
|
*/
|
1999-02-03 21:53:29 +00:00
|
|
|
[NSEvent startPeriodicEventsAfterDelay: 0.02 withPeriod: 0.03];
|
|
|
|
[[NSRunLoop currentRunLoop] limitDateForMode: NSEventTrackingRunLoopMode];
|
|
|
|
|
|
|
|
while ((eventType = [theEvent type]) != NSLeftMouseUp)
|
|
|
|
{
|
|
|
|
if (eventType != NSPeriodic)
|
|
|
|
{
|
|
|
|
apoint = [theEvent locationInWindow];
|
1999-06-06 08:19:19 +00:00
|
|
|
flags = [theEvent modifierFlags];
|
1999-02-03 21:53:29 +00:00
|
|
|
periodCount = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
1999-06-06 08:19:19 +00:00
|
|
|
/*
|
|
|
|
* if 6x periods have gone by w/o movement
|
|
|
|
* check mouse and update if necessary
|
|
|
|
*/
|
1999-02-03 21:53:29 +00:00
|
|
|
if (periodCount == 6)
|
1999-06-06 08:19:19 +00:00
|
|
|
{
|
|
|
|
apoint = [window mouseLocationOutsideOfEventStream];
|
|
|
|
periodCount = 0;
|
|
|
|
}
|
1999-02-03 21:53:29 +00:00
|
|
|
|
1999-02-05 06:44:40 +00:00
|
|
|
point = [self convertPoint: apoint fromView: nil];
|
|
|
|
point.x += xoffset;
|
|
|
|
point.y += yoffset;
|
1999-02-03 21:53:29 +00:00
|
|
|
|
|
|
|
if (point.x != knobRect.origin.x || point.y != knobRect.origin.y)
|
|
|
|
{
|
1999-06-06 08:19:19 +00:00
|
|
|
if (firstTime)
|
|
|
|
{
|
|
|
|
firstTime = NO;
|
|
|
|
}
|
|
|
|
else if (flags & NSAlternateKeyMask)
|
|
|
|
{
|
|
|
|
float diff;
|
|
|
|
|
|
|
|
diff = point.x - knobRect.origin.x;
|
|
|
|
diff = diff * 3 / 4;
|
|
|
|
xoffset -= diff;
|
|
|
|
point.x -= diff;
|
|
|
|
diff = point.y - knobRect.origin.y;
|
|
|
|
diff = diff * 3 / 4;
|
|
|
|
yoffset -= diff;
|
|
|
|
point.y -= diff;
|
|
|
|
}
|
|
|
|
|
1999-02-03 21:53:29 +00:00
|
|
|
floatValue = [self _floatValueForMousePointFromPreCalc: point];
|
|
|
|
|
|
|
|
if (floatValue != oldFloatValue)
|
1998-11-25 17:16:48 +00:00
|
|
|
{
|
1999-02-03 21:53:29 +00:00
|
|
|
[self setFloatValue: floatValue];
|
|
|
|
[self sendAction: _action to: _target];
|
|
|
|
|
1999-02-19 20:19:58 +00:00
|
|
|
/*
|
|
|
|
* Get current float value - which may have been changed
|
|
|
|
* when we sent the action to the target.
|
|
|
|
*/
|
|
|
|
oldFloatValue = _floatValue;
|
1999-02-03 21:53:29 +00:00
|
|
|
[window update];
|
1998-11-25 17:16:48 +00:00
|
|
|
}
|
1999-02-03 21:53:29 +00:00
|
|
|
knobRect.origin = point;
|
|
|
|
}
|
1999-06-06 08:19:19 +00:00
|
|
|
/*
|
|
|
|
* avoid timing related scrolling hesitation by counting number of
|
|
|
|
* periodic events since scroll pos was updated, when this reaches
|
|
|
|
* 6x periodic rate an update is forced on next periodic event
|
|
|
|
*/
|
1999-02-03 21:53:29 +00:00
|
|
|
periodCount++;
|
|
|
|
}
|
|
|
|
|
1999-06-06 08:19:19 +00:00
|
|
|
theEvent = [NSApp nextEventMatchingMask: eventMask
|
|
|
|
untilDate: theDistantFuture
|
|
|
|
inMode: NSEventTrackingRunLoopMode
|
|
|
|
dequeue: YES];
|
1999-02-03 21:53:29 +00:00
|
|
|
}
|
|
|
|
[NSEvent stopPeriodicEvents];
|
|
|
|
|
|
|
|
preCalcValues = NO;
|
|
|
|
}
|
1998-11-25 17:16:48 +00:00
|
|
|
|
1999-02-03 21:53:29 +00:00
|
|
|
- (void) trackScrollButtons: (NSEvent*)theEvent
|
|
|
|
{
|
1999-06-06 08:19:19 +00:00
|
|
|
NSApplication *theApp = [NSApplication sharedApplication];
|
|
|
|
unsigned int eventMask = NSLeftMouseDownMask | NSLeftMouseUpMask |
|
1999-02-03 21:53:29 +00:00
|
|
|
NSLeftMouseDraggedMask | NSMouseMovedMask;
|
1999-06-06 08:19:19 +00:00
|
|
|
NSPoint location;
|
|
|
|
BOOL shouldReturn = NO;
|
|
|
|
id theCell = nil;
|
|
|
|
NSRect rect;
|
1999-02-03 21:53:29 +00:00
|
|
|
|
|
|
|
NSDebugLog (@"trackScrollButtons");
|
|
|
|
do
|
|
|
|
{
|
|
|
|
location = [self convertPoint: [theEvent locationInWindow]fromView: nil];
|
|
|
|
_hitPart = [self testPart: location];
|
|
|
|
rect = [self rectForPart: _hitPart];
|
|
|
|
|
1999-06-11 07:22:37 +00:00
|
|
|
/*
|
|
|
|
* A hit on a scroller button should be a page meovement
|
|
|
|
* if the alt key is pressed.
|
|
|
|
*/
|
1999-02-03 21:53:29 +00:00
|
|
|
switch (_hitPart)
|
|
|
|
{
|
|
|
|
case NSScrollerIncrementLine:
|
1999-06-11 07:22:37 +00:00
|
|
|
if ([theEvent modifierFlags] & NSAlternateKeyMask)
|
|
|
|
{
|
|
|
|
_hitPart = NSScrollerIncrementPage;
|
|
|
|
}
|
|
|
|
/* Fall through to next case */
|
1999-02-03 21:53:29 +00:00
|
|
|
case NSScrollerIncrementPage:
|
1999-03-14 10:58:59 +00:00
|
|
|
theCell = (_isHorizontal ? rightCell : downCell);
|
1999-02-03 21:53:29 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case NSScrollerDecrementLine:
|
1999-06-11 07:22:37 +00:00
|
|
|
if ([theEvent modifierFlags] & NSAlternateKeyMask)
|
|
|
|
{
|
|
|
|
_hitPart = NSScrollerDecrementPage;
|
|
|
|
}
|
|
|
|
/* Fall through to next case */
|
1999-02-03 21:53:29 +00:00
|
|
|
case NSScrollerDecrementPage:
|
1999-03-14 10:58:59 +00:00
|
|
|
theCell = (_isHorizontal ? leftCell : upCell);
|
1999-02-03 21:53:29 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
theCell = nil;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (theCell)
|
|
|
|
{
|
|
|
|
[self lockFocus];
|
|
|
|
[theCell highlight: YES withFrame: rect inView: self];
|
|
|
|
[self unlockFocus];
|
|
|
|
[window flushWindow];
|
|
|
|
|
|
|
|
NSLog (@"tracking cell %x", theCell);
|
|
|
|
|
|
|
|
shouldReturn = [theCell trackMouse: theEvent
|
|
|
|
inRect: rect
|
|
|
|
ofView: self
|
|
|
|
untilMouseUp: YES];
|
|
|
|
|
|
|
|
[self lockFocus];
|
|
|
|
[theCell highlight: NO withFrame: rect inView: self];
|
|
|
|
[self unlockFocus];
|
|
|
|
[window flushWindow];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (shouldReturn)
|
|
|
|
break;
|
|
|
|
|
|
|
|
theEvent = [theApp nextEventMatchingMask: eventMask
|
|
|
|
untilDate: [NSDate distantFuture]
|
|
|
|
inMode: NSEventTrackingRunLoopMode
|
|
|
|
dequeue: YES];
|
|
|
|
}
|
|
|
|
while ([theEvent type] != NSLeftMouseUp);
|
|
|
|
|
|
|
|
NSDebugLog (@"return from trackScrollButtons");
|
|
|
|
}
|
1998-10-19 06:10:49 +00:00
|
|
|
|
1999-06-06 08:19:19 +00:00
|
|
|
/*
|
|
|
|
* draw the scroller
|
|
|
|
*/
|
1999-02-03 21:53:29 +00:00
|
|
|
- (void) drawRect: (NSRect)rect
|
1997-08-05 21:50:10 +00:00
|
|
|
{
|
1999-02-03 21:53:29 +00:00
|
|
|
NSDebugLog (@"NSScroller drawRect: ((%f, %f), (%f, %f))",
|
|
|
|
rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);
|
|
|
|
|
1999-03-14 10:58:59 +00:00
|
|
|
[self drawKnobSlot];
|
|
|
|
[self drawKnob];
|
1999-03-14 18:10:42 +00:00
|
|
|
|
1999-02-03 21:53:29 +00:00
|
|
|
[self drawArrow: NSScrollerDecrementArrow highlight: NO];
|
|
|
|
[self drawArrow: NSScrollerIncrementArrow highlight: NO];
|
1997-03-05 01:11:17 +00:00
|
|
|
}
|
|
|
|
|
1999-02-03 21:53:29 +00:00
|
|
|
- (void) drawArrow: (NSScrollerArrow)whichButton highlight: (BOOL)flag
|
1997-03-05 01:11:17 +00:00
|
|
|
{
|
1999-02-03 21:53:29 +00:00
|
|
|
NSRect rect = [self rectForPart: (whichButton == NSScrollerIncrementArrow
|
|
|
|
? NSScrollerIncrementLine : NSScrollerDecrementLine)];
|
|
|
|
id theCell = nil;
|
|
|
|
|
|
|
|
NSDebugLog (@"position of %s cell is (%f, %f)",
|
|
|
|
(whichButton == NSScrollerIncrementArrow ? "increment" : "decrement"),
|
|
|
|
rect.origin.x, rect.origin.y);
|
|
|
|
|
|
|
|
switch (whichButton)
|
|
|
|
{
|
|
|
|
case NSScrollerDecrementArrow:
|
1999-03-14 10:58:59 +00:00
|
|
|
theCell = (_isHorizontal ? leftCell : upCell);
|
1999-02-03 21:53:29 +00:00
|
|
|
break;
|
|
|
|
case NSScrollerIncrementArrow:
|
1999-03-14 10:58:59 +00:00
|
|
|
theCell = (_isHorizontal ? rightCell : downCell);
|
1999-02-03 21:53:29 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
[theCell drawWithFrame: rect inView: self];
|
1997-03-05 01:11:17 +00:00
|
|
|
}
|
|
|
|
|
1999-02-03 21:53:29 +00:00
|
|
|
- (void) drawKnob
|
1997-03-05 01:11:17 +00:00
|
|
|
{
|
1999-02-03 21:53:29 +00:00
|
|
|
[knobCell drawWithFrame: [self rectForPart: NSScrollerKnob] inView: self];
|
1997-03-05 01:11:17 +00:00
|
|
|
}
|
|
|
|
|
1999-02-03 21:53:29 +00:00
|
|
|
- (void) drawKnobSlot
|
1997-03-05 01:11:17 +00:00
|
|
|
{
|
1999-02-03 21:53:29 +00:00
|
|
|
NSRect rect;
|
1998-11-25 17:16:48 +00:00
|
|
|
|
1999-06-06 08:19:19 +00:00
|
|
|
/*
|
|
|
|
* in a modal loop we have already pre calc'd our parts
|
|
|
|
*/
|
1999-02-03 21:53:29 +00:00
|
|
|
if (preCalcValues)
|
|
|
|
rect = slotRect;
|
|
|
|
else
|
|
|
|
rect = [self rectForPart: NSScrollerKnobSlot];
|
1998-11-25 17:16:48 +00:00
|
|
|
|
1999-03-16 16:38:26 +00:00
|
|
|
[[NSColor scrollBarColor] set];
|
1999-02-03 21:53:29 +00:00
|
|
|
NSRectFill(rect);
|
1997-03-05 01:11:17 +00:00
|
|
|
}
|
|
|
|
|
1999-03-14 10:58:59 +00:00
|
|
|
- (void) highlight: (BOOL)flag
|
|
|
|
{
|
|
|
|
switch (_hitPart)
|
|
|
|
{
|
|
|
|
case NSScrollerIncrementLine:
|
|
|
|
case NSScrollerIncrementPage:
|
|
|
|
[self drawArrow: NSScrollerIncrementArrow highlight: flag];
|
|
|
|
break;
|
|
|
|
|
|
|
|
case NSScrollerDecrementLine:
|
|
|
|
case NSScrollerDecrementPage:
|
|
|
|
[self drawArrow: NSScrollerDecrementArrow highlight: flag];
|
|
|
|
break;
|
|
|
|
|
1999-06-06 08:19:19 +00:00
|
|
|
default: /* No button currently hit for highlighting. */
|
1999-03-14 10:58:59 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-02-05 06:44:40 +00:00
|
|
|
- (NSRect) rectForPart: (NSScrollerPart)partCode
|
1998-09-08 14:56:29 +00:00
|
|
|
{
|
1999-02-03 21:53:29 +00:00
|
|
|
NSRect scrollerFrame = frame;
|
1999-03-16 16:38:26 +00:00
|
|
|
float x = 1, y = 1;
|
1999-03-14 10:58:59 +00:00
|
|
|
float width, height;
|
1999-03-16 16:38:26 +00:00
|
|
|
float buttonsSize = 2 * buttonsWidth + 2;
|
1999-02-03 21:53:29 +00:00
|
|
|
NSUsableScrollerParts usableParts;
|
1999-06-06 08:19:19 +00:00
|
|
|
/*
|
|
|
|
* If the scroller is disabled then the scroller buttons and the
|
|
|
|
* knob are not displayed at all.
|
|
|
|
*/
|
1999-02-03 21:53:29 +00:00
|
|
|
if (!_isEnabled)
|
|
|
|
usableParts = NSNoScrollerParts;
|
|
|
|
else
|
|
|
|
usableParts = _usableParts;
|
|
|
|
|
1999-06-06 08:19:19 +00:00
|
|
|
/*
|
|
|
|
* Assign to `width' and `height' values describing
|
|
|
|
* the width and height of the scroller regardless
|
|
|
|
* of its orientation.
|
|
|
|
* but keeps track of the scroller's orientation.
|
|
|
|
*/
|
1999-02-03 21:53:29 +00:00
|
|
|
if (_isHorizontal)
|
|
|
|
{
|
1999-03-16 16:38:26 +00:00
|
|
|
width = scrollerFrame.size.height - 2;
|
|
|
|
height = scrollerFrame.size.width - 2;
|
1999-02-03 21:53:29 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
1999-03-16 16:38:26 +00:00
|
|
|
width = scrollerFrame.size.width - 2;
|
|
|
|
height = scrollerFrame.size.height - 2;
|
1999-02-03 21:53:29 +00:00
|
|
|
}
|
1999-03-14 10:58:59 +00:00
|
|
|
|
1999-06-06 08:19:19 +00:00
|
|
|
/*
|
|
|
|
* The x, y, width and height values are computed below for the vertical
|
|
|
|
* scroller. The height of the scroll buttons is assumed to be equal to
|
|
|
|
* the width.
|
|
|
|
*/
|
1999-02-03 21:53:29 +00:00
|
|
|
switch (partCode)
|
|
|
|
{
|
|
|
|
case NSScrollerKnob:
|
|
|
|
{
|
|
|
|
float knobHeight, knobPosition, slotHeight;
|
1999-06-06 08:19:19 +00:00
|
|
|
|
|
|
|
if (usableParts == NSNoScrollerParts
|
|
|
|
|| usableParts == NSOnlyScrollerArrows)
|
1999-02-03 21:53:29 +00:00
|
|
|
return NSZeroRect;
|
1999-06-06 08:19:19 +00:00
|
|
|
|
|
|
|
/* calc the slot Height */
|
|
|
|
slotHeight = height - (_arrowsPosition == NSScrollerArrowsNone
|
|
|
|
? 0 : buttonsSize);
|
1999-02-03 21:53:29 +00:00
|
|
|
knobHeight = _knobProportion * slotHeight;
|
|
|
|
if (knobHeight < buttonsWidth)
|
|
|
|
knobHeight = buttonsWidth;
|
1999-06-06 08:19:19 +00:00
|
|
|
|
|
|
|
/* calc knob's position */
|
1999-03-14 10:58:59 +00:00
|
|
|
knobPosition = _floatValue * (slotHeight - knobHeight);
|
1999-06-06 08:19:19 +00:00
|
|
|
knobPosition = (float)floor(knobPosition);
|
|
|
|
|
|
|
|
/* calc actual position */
|
1999-03-16 16:38:26 +00:00
|
|
|
y += knobPosition + (_arrowsPosition == NSScrollerArrowsMaxEnd
|
1999-06-06 08:19:19 +00:00
|
|
|
|| _arrowsPosition == NSScrollerArrowsNone ? 0 : buttonsSize);
|
1999-02-03 21:53:29 +00:00
|
|
|
height = knobHeight;
|
|
|
|
width = buttonsWidth;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case NSScrollerKnobSlot:
|
1999-06-06 08:19:19 +00:00
|
|
|
/*
|
|
|
|
* if the scroller does not have buttons the slot completely
|
|
|
|
* fills the scroller.
|
|
|
|
*/
|
1999-03-16 16:38:26 +00:00
|
|
|
if (usableParts == NSNoScrollerParts
|
|
|
|
|| _arrowsPosition == NSScrollerArrowsNone)
|
1999-02-03 21:53:29 +00:00
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
1999-03-16 16:38:26 +00:00
|
|
|
height -= buttonsSize;
|
|
|
|
if (_arrowsPosition == NSScrollerArrowsMinEnd)
|
1999-02-03 21:53:29 +00:00
|
|
|
{
|
1999-03-16 16:38:26 +00:00
|
|
|
y += buttonsSize;
|
1999-02-03 21:53:29 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case NSScrollerDecrementLine:
|
|
|
|
case NSScrollerDecrementPage:
|
1999-03-16 16:38:26 +00:00
|
|
|
if (usableParts == NSNoScrollerParts
|
|
|
|
|| _arrowsPosition == NSScrollerArrowsNone)
|
1999-02-03 21:53:29 +00:00
|
|
|
{
|
1999-03-16 16:38:26 +00:00
|
|
|
return NSZeroRect;
|
1999-02-03 21:53:29 +00:00
|
|
|
}
|
1999-03-16 16:38:26 +00:00
|
|
|
else if (_arrowsPosition == NSScrollerArrowsMaxEnd)
|
1999-03-14 10:58:59 +00:00
|
|
|
{
|
1999-03-16 16:38:26 +00:00
|
|
|
y += (height - buttonsSize + 1);
|
1999-03-14 10:58:59 +00:00
|
|
|
}
|
|
|
|
width = buttonsWidth;
|
1999-02-03 21:53:29 +00:00
|
|
|
height = buttonsWidth;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case NSScrollerIncrementLine:
|
|
|
|
case NSScrollerIncrementPage:
|
1999-03-16 16:38:26 +00:00
|
|
|
if (usableParts == NSNoScrollerParts
|
|
|
|
|| _arrowsPosition == NSScrollerArrowsNone)
|
|
|
|
{
|
|
|
|
return NSZeroRect;
|
|
|
|
}
|
|
|
|
else if (_arrowsPosition == NSScrollerArrowsMaxEnd)
|
1999-03-14 10:58:59 +00:00
|
|
|
{
|
1999-03-16 16:38:26 +00:00
|
|
|
y += (height - buttonsWidth);
|
1999-03-14 10:58:59 +00:00
|
|
|
}
|
|
|
|
else if (_arrowsPosition == NSScrollerArrowsMinEnd)
|
1999-02-03 21:53:29 +00:00
|
|
|
{
|
1999-03-16 16:38:26 +00:00
|
|
|
y += (buttonsWidth + 1);
|
1999-02-03 21:53:29 +00:00
|
|
|
}
|
|
|
|
height = buttonsWidth;
|
1999-03-14 10:58:59 +00:00
|
|
|
width = buttonsWidth;
|
1999-02-03 21:53:29 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case NSScrollerNoPart:
|
|
|
|
return NSZeroRect;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_isHorizontal)
|
|
|
|
return NSMakeRect (y, x, height, width);
|
|
|
|
else
|
|
|
|
return NSMakeRect (x, y, width, height);
|
1998-09-08 14:56:29 +00:00
|
|
|
}
|
1997-08-05 21:50:10 +00:00
|
|
|
|
1997-03-05 01:11:17 +00:00
|
|
|
@end
|