Changed the class NSScroller to be more similar to the the current Apple

specification.


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@28671 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
fredkiefer 2009-09-14 19:00:07 +00:00
parent 5330332f98
commit 80e0875d45
2 changed files with 251 additions and 158 deletions

View file

@ -38,7 +38,10 @@
@class NSEvent; @class NSEvent;
typedef enum _NSScrollArrowPosition { typedef enum _NSScrollArrowPosition {
NSScrollerArrowsMaxEnd, #if OS_API_VERSION(MAC_OS_X_VERSION_10_1, GS_API_LATEST)
NSScrollerArrowsDefaultSetting = 0,
#endif
NSScrollerArrowsMaxEnd = 0,
NSScrollerArrowsMinEnd, NSScrollerArrowsMinEnd,
NSScrollerArrowsNone NSScrollerArrowsNone
} NSScrollArrowPosition; } NSScrollArrowPosition;
@ -60,29 +63,33 @@ typedef enum _NSScrollerUsablePart {
} NSUsableScrollerParts; } NSUsableScrollerParts;
typedef enum _NSScrollerArrow { typedef enum _NSScrollerArrow {
NSScrollerIncrementArrow, NSScrollerIncrementArrow = 0,
NSScrollerDecrementArrow NSScrollerDecrementArrow
} NSScrollerArrow; } NSScrollerArrow;
@interface NSScroller : NSControl <NSCoding> @interface NSScroller : NSControl <NSCoding>
{ {
float _floatValue; double _doubleValue;
float _knobProportion; float _knobProportion;
float _pendingKnobProportion; float _pendingKnobProportion;
id _target; id _target;
SEL _action; SEL _action;
BOOL _isHorizontal;
BOOL _isEnabled;
NSScrollerPart _hitPart; NSScrollerPart _hitPart;
NSScrollArrowPosition _arrowsPosition; NSScrollArrowPosition _arrowsPosition;
NSUsableScrollerParts _usableParts; NSUsableScrollerParts _usableParts;
BOOL _cacheValid; struct _scFlagsType {
// total 7 bits. 25 bits left.
unsigned isHorizontal: 1;
unsigned isEnabled: 1;
unsigned control_tint: 3;
unsigned control_size: 2;
} _scFlags;
} }
// //
// Laying out the NSScroller // Laying out the NSScroller
// //
+ (float)scrollerWidth; + (CGFloat)scrollerWidth;
- (NSScrollArrowPosition)arrowsPosition; - (NSScrollArrowPosition)arrowsPosition;
- (void)checkSpaceForParts; - (void)checkSpaceForParts;
- (NSRect)rectForPart:(NSScrollerPart)partCode; - (NSRect)rectForPart:(NSScrollerPart)partCode;
@ -92,8 +99,10 @@ typedef enum _NSScrollerArrow {
// //
// Setting the NSScroller's Values // Setting the NSScroller's Values
// //
- (float)knobProportion; - (CGFloat)knobProportion;
- (void)setFloatValue:(float)aFloat knobProportion:(float)ratio; #if OS_API_VERSION(GS_API_MACOSX, MAC_OS_X_VERSION_10_5)
- (void)setFloatValue:(float)aFloat knobProportion:(CGFloat)ratio;
#endif
// //
// Displaying // Displaying
@ -117,13 +126,18 @@ typedef enum _NSScrollerArrow {
- (void)trackScrollButtons:(NSEvent *)theEvent; - (void)trackScrollButtons:(NSEvent *)theEvent;
#if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST) #if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST)
+ (float)scrollerWidthForControlSize:(NSControlSize)controlSize; + (CGFloat)scrollerWidthForControlSize:(NSControlSize)controlSize;
- (void)setControlSize:(NSControlSize)controlSize; - (void)setControlSize:(NSControlSize)controlSize;
- (NSControlSize)controlSize; - (NSControlSize)controlSize;
- (void)setControlTint:(NSControlTint)controlTint; - (void)setControlTint:(NSControlTint)controlTint;
- (NSControlTint)controlTint; - (NSControlTint)controlTint;
#endif #endif
#if OS_API_VERSION(MAC_OS_X_VERSION_10_5, GS_API_LATEST)
- (void)setKnobProportion:(CGFloat)proportion;
- (void)drawKnobSlotInRect:(NSRect)slotRect highlight:(BOOL)flag;
#endif
@end @end
#endif // _GNUstep_H_NSScroller #endif // _GNUstep_H_NSScroller

View file

@ -106,6 +106,12 @@ static const float buttonsOffset = 2; // buttonsWidth = sw - buttonsOffset
*/ */
+ (float) scrollerWidth + (float) scrollerWidth
{ {
return [self scrollerWidthForControlSize: NSRegularControlSize];
}
+ (float) scrollerWidthForControlSize: (NSControlSize)controlSize
{
// FIXME
if (scrollerWidth == 0.0) if (scrollerWidth == 0.0)
{ {
scrollerWidth = [[GSTheme theme] defaultScrollerWidth]; scrollerWidth = [[GSTheme theme] defaultScrollerWidth];
@ -164,9 +170,14 @@ static const float buttonsOffset = 2; // buttonsWidth = sw - buttonsOffset
return _hitPart; return _hitPart;
} }
- (double) doubleValue
{
return _doubleValue;
}
- (float) floatValue - (float) floatValue
{ {
return _floatValue; return _doubleValue;
} }
- (void) setAction: (SEL)action - (void) setAction: (SEL)action
@ -193,11 +204,30 @@ static const float buttonsOffset = 2; // buttonsWidth = sw - buttonsOffset
{ {
[super encodeWithCoder: aCoder]; [super encodeWithCoder: aCoder];
[aCoder encodeValueOfObjCType: @encode(unsigned int) at: &_arrowsPosition]; if ([aCoder allowsKeyedCoding])
[aCoder encodeValueOfObjCType: @encode(BOOL) at: &_isEnabled]; {
[aCoder encodeConditionalObject: _target]; if (_target)
[aCoder encodeValueOfObjCType: @encode(SEL) at: &_action]; {
/* We do not save float value, knob proportion. */ [aCoder encodeObject: _target forKey: @"NSTarget"];
}
if (_action != NULL)
{
[aCoder encodeObject: NSStringFromSelector(_action) forKey: @"NSAction"];
}
[aCoder encodeFloat: [self floatValue] forKey: @"NSCurValue"];
[aCoder encodeFloat: [self knobProportion] * 100.0 forKey: @"NSPercent"];
}
else
{
BOOL flag;
[aCoder encodeValueOfObjCType: @encode(unsigned int) at: &_arrowsPosition];
flag = _scFlags.isEnabled;
[aCoder encodeValueOfObjCType: @encode(BOOL) at: &flag];
[aCoder encodeConditionalObject: _target];
[aCoder encodeValueOfObjCType: @encode(SEL) at: &_action];
/* We do not save float value, knob proportion. */
}
} }
- (id) initWithCoder: (NSCoder*)aDecoder - (id) initWithCoder: (NSCoder*)aDecoder
@ -206,51 +236,64 @@ static const float buttonsOffset = 2; // buttonsWidth = sw - buttonsOffset
if ([aDecoder allowsKeyedCoding]) if ([aDecoder allowsKeyedCoding])
{ {
NSString *action = [aDecoder decodeObjectForKey: @"NSAction"];
id target = [aDecoder decodeObjectForKey: @"NSTarget"];
float value = 0.0;
float percent = 0.0;
int flags;
if (_frame.size.width > _frame.size.height) if (_frame.size.width > _frame.size.height)
{ {
_isHorizontal = YES; _scFlags.isHorizontal = YES;
} }
else else
{ {
_isHorizontal = NO; _scFlags.isHorizontal = NO;
} }
if (_isHorizontal) if (_scFlags.isHorizontal)
{ {
_floatValue = 0.0; _doubleValue = 0.0;
} }
else else
{ {
_floatValue = 1.0; _doubleValue = 1.0;
} }
if (action != nil) if ([aDecoder containsValueForKey: @"NSAction"])
{ {
[self setAction: NSSelectorFromString(action)]; NSString *action = [aDecoder decodeObjectForKey: @"NSAction"];
} if (action != nil)
[self setTarget: target]; {
[self setAction: NSSelectorFromString(action)];
}
}
if ([aDecoder containsValueForKey: @"NSTarget"])
{
id target = [aDecoder decodeObjectForKey: @"NSTarget"];
[self setTarget: target];
}
if ([aDecoder containsValueForKey: @"NSCurValue"]) if ([aDecoder containsValueForKey: @"NSCurValue"])
{ {
value = [aDecoder decodeFloatForKey: @"NSCurValue"]; float value = [aDecoder decodeFloatForKey: @"NSCurValue"];
[self setFloatValue: value];
} }
if ([aDecoder containsValueForKey: @"NSPercent"]) if ([aDecoder containsValueForKey: @"NSPercent"])
{ {
percent = [aDecoder decodeFloatForKey: @"NSPercent"]; float percent = [aDecoder decodeFloatForKey: @"NSPercent"];
[self setKnobProportion: percent / 100.0];
} }
[self setFloatValue: value knobProportion: percent];
if ([aDecoder containsValueForKey: @"NSsFlags"]) if ([aDecoder containsValueForKey: @"NSsFlags"])
{ {
int flags;
flags = [aDecoder decodeIntForKey: @"NSsFlags"]; flags = [aDecoder decodeIntForKey: @"NSsFlags"];
// is horiz is set above... // is horiz is set above...
[self setControlTint: ((flags >> 16) & 7)];
[self setArrowsPosition: ((flags >> 29) & 3)];
_usableParts = ((flags >> 27) & 3);
}
if ([aDecoder containsValueForKey: @"NSsFlags2"])
{
int flags2;
flags2 = [aDecoder decodeIntForKey: @"NSsFlags2"];
[self setControlSize: ((flags2 >> 26) & 3)];
} }
// setup... // setup...
@ -261,34 +304,37 @@ static const float buttonsOffset = 2; // buttonsWidth = sw - buttonsOffset
} }
else else
{ {
BOOL flag;
if (_frame.size.width > _frame.size.height) if (_frame.size.width > _frame.size.height)
{ {
_isHorizontal = YES; _scFlags.isHorizontal = YES;
} }
else else
{ {
_isHorizontal = NO; _scFlags.isHorizontal = NO;
} }
if (_isHorizontal) if (_scFlags.isHorizontal)
{ {
_floatValue = 0.0; _doubleValue = 0.0;
} }
else else
{ {
_floatValue = 1.0; _doubleValue = 1.0;
} }
_hitPart = NSScrollerNoPart;
[aDecoder decodeValueOfObjCType: @encode(unsigned int) [aDecoder decodeValueOfObjCType: @encode(unsigned int)
at: &_arrowsPosition]; at: &_arrowsPosition];
[aDecoder decodeValueOfObjCType: @encode(BOOL) at: &_isEnabled]; [aDecoder decodeValueOfObjCType: @encode(BOOL) at: &flag];
_scFlags.isEnabled = flag;
[aDecoder decodeValueOfObjCType: @encode(id) at: &_target]; [aDecoder decodeValueOfObjCType: @encode(id) at: &_target];
// Undo RETAIN by decoder // Undo RETAIN by decoder
TEST_RELEASE(_target); TEST_RELEASE(_target);
[aDecoder decodeValueOfObjCType: @encode(SEL) at: &_action]; [aDecoder decodeValueOfObjCType: @encode(SEL) at: &_action];
_hitPart = NSScrollerNoPart;
[self drawParts]; [self drawParts];
[self checkSpaceForParts]; [self checkSpaceForParts];
} }
@ -308,41 +354,38 @@ static const float buttonsOffset = 2; // buttonsWidth = sw - buttonsOffset
*/ */
if (frameRect.size.width > frameRect.size.height) if (frameRect.size.width > frameRect.size.height)
{ {
_isHorizontal = YES; _scFlags.isHorizontal = YES;
frameRect.size.height = [isa scrollerWidth]; frameRect.size.height = [isa scrollerWidth];
} }
else else
{ {
_isHorizontal = NO; _scFlags.isHorizontal = NO;
frameRect.size.width = [isa scrollerWidth]; frameRect.size.width = [isa scrollerWidth];
} }
[super initWithFrame: frameRect]; self = [super initWithFrame: frameRect];
if (!self)
return nil;
if (_isHorizontal) if (_scFlags.isHorizontal)
{ {
_arrowsPosition = NSScrollerArrowsMinEnd; _arrowsPosition = NSScrollerArrowsMinEnd;
_floatValue = 0.0; _doubleValue = 0.0;
} }
else else
{ {
_arrowsPosition = NSScrollerArrowsMaxEnd; _arrowsPosition = NSScrollerArrowsMaxEnd;
_floatValue = 1.0; _doubleValue = 1.0;
} }
_hitPart = NSScrollerNoPart; _hitPart = NSScrollerNoPart;
[self drawParts];
[self setEnabled: NO]; [self setEnabled: NO];
[self drawParts];
[self checkSpaceForParts]; [self checkSpaceForParts];
return self; return self;
} }
- (id) init
{
return [self initWithFrame: NSZeroRect];
}
/** /**
* Cache images for scroll arrows and knob. If you override +scrollerWidth * Cache images for scroll arrows and knob. If you override +scrollerWidth
* you may need to override this as well (to provide images for the new * you may need to override this as well (to provide images for the new
@ -411,9 +454,9 @@ static const float buttonsOffset = 2; // buttonsWidth = sw - buttonsOffset
- (void) checkSpaceForParts - (void) checkSpaceForParts
{ {
NSSize frameSize = _frame.size; NSSize frameSize = _frame.size;
float size = (_isHorizontal ? frameSize.width : frameSize.height); float size = (_scFlags.isHorizontal ? frameSize.width : frameSize.height);
int buttonsWidth = [isa scrollerWidth] - buttonsOffset; int buttonsWidth = [isa scrollerWidth] - buttonsOffset;
if (_arrowsPosition == NSScrollerArrowsNone) if (_arrowsPosition == NSScrollerArrowsNone)
{ {
@ -445,13 +488,12 @@ static const float buttonsOffset = 2; // buttonsWidth = sw - buttonsOffset
- (void) setEnabled: (BOOL)flag - (void) setEnabled: (BOOL)flag
{ {
if (_isEnabled == flag) if (_scFlags.isEnabled == flag)
{ {
return; return;
} }
_isEnabled = flag; _scFlags.isEnabled = flag;
_cacheValid = NO;
[self setNeedsDisplay: YES]; [self setNeedsDisplay: YES];
} }
@ -472,62 +514,61 @@ static const float buttonsOffset = 2; // buttonsWidth = sw - buttonsOffset
} }
_arrowsPosition = where; _arrowsPosition = where;
_cacheValid = NO;
[self setNeedsDisplay: YES]; [self setNeedsDisplay: YES];
} }
- (void) setFloatValue: (float)aFloat - (void) setFloatValue: (float)aFloat
{ {
if (_floatValue == aFloat) [self setDoubleValue: aFloat];
}
- (void) setDoubleValue: (double)aDouble
{
if (_doubleValue == aDouble)
{ {
/* Most likely our trackKnob method initiated this via NSScrollView */ /* Most likely our trackKnob method initiated this via NSScrollView */
return; return;
} }
if (aFloat < 0) if (aDouble < 0.0)
{ {
_floatValue = 0; _doubleValue = 0.0;
} }
else if (aFloat > 1) else if (aDouble > 1.0)
{ {
_floatValue = 1; _doubleValue = 1.0;
} }
else else
{ {
_floatValue = aFloat; _doubleValue = aDouble;
} }
[self setNeedsDisplayInRect: [self rectForPart: NSScrollerKnobSlot]]; [self setNeedsDisplayInRect: [self rectForPart: NSScrollerKnobSlot]];
} }
- (void) setFloatValue: (float)aFloat knobProportion: (float)ratio - (void) setKnobProportion: (CGFloat)proportion
{ {
if (_floatValue == aFloat && _knobProportion == ratio) if (_knobProportion == proportion)
{ {
/* Most likely our trackKnob method initiated this via NSScrollView */ /* Most likely our trackKnob method initiated this via NSScrollView */
return; return;
} }
if (ratio < 0) if (proportion < 0.0)
{ {
_pendingKnobProportion = 0; _knobProportion = 0.0;
} }
else if (ratio > 1) else if (proportion > 1.0)
{ {
_pendingKnobProportion = 1; _knobProportion = 1.0;
} }
else else
{ {
_pendingKnobProportion = ratio; _knobProportion = proportion;
}
if (_hitPart == NSScrollerNoPart)
{
_knobProportion = _pendingKnobProportion;
_pendingKnobProportion = 0;
} }
[self setNeedsDisplayInRect: [self rectForPart: NSScrollerKnobSlot]];
// Handle the case when parts should disappear // Handle the case when parts should disappear
if (_knobProportion == 1) if (_knobProportion == 1.0)
{ {
[self setEnabled: NO]; [self setEnabled: NO];
} }
@ -535,12 +576,24 @@ static const float buttonsOffset = 2; // buttonsWidth = sw - buttonsOffset
{ {
[self setEnabled: YES]; [self setEnabled: YES];
} }
}
- (void) setFloatValue: (float)aFloat knobProportion: (CGFloat)ratio
{
if (_hitPart == NSScrollerNoPart)
{
[self setKnobProportion: ratio];
}
else
{
_pendingKnobProportion = ratio;
}
// Don't set float value if knob is being dragged // Don't set float value if knob is being dragged
if (_hitPart != NSScrollerKnobSlot && _hitPart != NSScrollerKnob) if (_hitPart != NSScrollerKnobSlot && _hitPart != NSScrollerKnob)
{ {
/* Make sure we mark ourselves as needing redisplay. */ /* Make sure we mark ourselves as needing redisplay. */
_floatValue = -1; _doubleValue = -1;
[self setFloatValue: aFloat]; [self setFloatValue: aFloat];
} }
@ -553,12 +606,12 @@ static const float buttonsOffset = 2; // buttonsWidth = sw - buttonsOffset
*/ */
if (frameRect.size.width > frameRect.size.height) if (frameRect.size.width > frameRect.size.height)
{ {
_isHorizontal = YES; _scFlags.isHorizontal = YES;
frameRect.size.height = [isa scrollerWidth]; frameRect.size.height = [isa scrollerWidth];
} }
else else
{ {
_isHorizontal = NO; _scFlags.isHorizontal = NO;
frameRect.size.width = [isa scrollerWidth]; frameRect.size.width = [isa scrollerWidth];
} }
@ -566,7 +619,7 @@ static const float buttonsOffset = 2; // buttonsWidth = sw - buttonsOffset
if (_arrowsPosition != NSScrollerArrowsNone) if (_arrowsPosition != NSScrollerArrowsNone)
{ {
if (_isHorizontal) if (_scFlags.isHorizontal)
{ {
_arrowsPosition = NSScrollerArrowsMinEnd; _arrowsPosition = NSScrollerArrowsMinEnd;
} }
@ -577,23 +630,48 @@ static const float buttonsOffset = 2; // buttonsWidth = sw - buttonsOffset
} }
_hitPart = NSScrollerNoPart; _hitPart = NSScrollerNoPart;
_cacheValid = NO;
[self checkSpaceForParts]; [self checkSpaceForParts];
} }
- (void) setFrameSize: (NSSize)size - (void) setFrameSize: (NSSize)size
{ {
/*
* determine the orientation of the scroller and adjust it's size accordingly
*/
if (size.width > size.height)
{
_scFlags.isHorizontal = YES;
size.height = [isa scrollerWidth];
}
else
{
_scFlags.isHorizontal = NO;
size.width = [isa scrollerWidth];
}
[super setFrameSize: size]; [super setFrameSize: size];
if (_arrowsPosition != NSScrollerArrowsNone)
{
if (_scFlags.isHorizontal)
{
_arrowsPosition = NSScrollerArrowsMinEnd;
}
else
{
_arrowsPosition = NSScrollerArrowsMaxEnd;
}
}
_hitPart = NSScrollerNoPart;
[self checkSpaceForParts]; [self checkSpaceForParts];
_cacheValid = NO;
[self setNeedsDisplay: YES];
} }
/**<p>Returns the NSScroller's part under the point <var>thePoint</var>. /**<p>Returns the NSScroller's part under the point <var>thePoint</var>.
See <ref type="type" id="NSScrollerPart">NSScrollerPart</ref> for more See <ref type="type" id="NSScrollerPart">NSScrollerPart</ref> for more
informations</p> informations</p>
*/ */
- (NSScrollerPart)testPart: (NSPoint)thePoint - (NSScrollerPart) testPart: (NSPoint)thePoint
{ {
/* /*
* return what part of the scroller the mouse hit * return what part of the scroller the mouse hit
@ -635,7 +713,7 @@ static const float buttonsOffset = 2; // buttonsWidth = sw - buttonsOffset
return NSScrollerNoPart; return NSScrollerNoPart;
} }
- (float) _floatValueForMousePoint: (NSPoint)point - (double) _doubleValueForMousePoint: (NSPoint)point
{ {
NSRect knobRect = [self rectForPart: NSScrollerKnob]; NSRect knobRect = [self rectForPart: NSScrollerKnob];
NSRect slotRect = [self rectForPart: NSScrollerKnobSlot]; NSRect slotRect = [self rectForPart: NSScrollerKnobSlot];
@ -646,7 +724,7 @@ static const float buttonsOffset = 2; // buttonsWidth = sw - buttonsOffset
/* /*
* Compute limits and mouse position * Compute limits and mouse position
*/ */
if (_isHorizontal) if (_scFlags.isHorizontal)
{ {
min_pos = NSMinX(slotRect) + NSWidth(knobRect) / 2; min_pos = NSMinX(slotRect) + NSWidth(knobRect) / 2;
max_pos = NSMaxX(slotRect) - NSWidth(knobRect) / 2; max_pos = NSMaxX(slotRect) - NSWidth(knobRect) / 2;
@ -692,10 +770,10 @@ static const float buttonsOffset = 2; // buttonsWidth = sw - buttonsOffset
case NSScrollerKnobSlot: case NSScrollerKnobSlot:
{ {
float floatValue = [self _floatValueForMousePoint: double doubleValue = [self _doubleValueForMousePoint:
[self convertPoint: location [self convertPoint: location
fromView: nil]]; fromView: nil]];
if (floatValue != _floatValue) if (doubleValue != _doubleValue)
{ {
NSInterfaceStyle interfaceStyle; NSInterfaceStyle interfaceStyle;
@ -707,14 +785,14 @@ static const float buttonsOffset = 2; // buttonsWidth = sw - buttonsOffset
{ {
/* NeXTstep style is to scroll to point. /* NeXTstep style is to scroll to point.
*/ */
[self setFloatValue: floatValue]; [self setDoubleValue: doubleValue];
[self sendAction: _action to: _target]; [self sendAction: _action to: _target];
} }
else else
{ {
/* Windows style is to scroll by a page. /* Windows style is to scroll by a page.
*/ */
if (floatValue > _floatValue) if (doubleValue > _doubleValue)
{ {
_hitPart = NSScrollerIncrementPage; _hitPart = NSScrollerIncrementPage;
} }
@ -736,7 +814,8 @@ static const float buttonsOffset = 2; // buttonsWidth = sw - buttonsOffset
_hitPart = NSScrollerNoPart; _hitPart = NSScrollerNoPart;
if (_pendingKnobProportion) if (_pendingKnobProportion)
{ {
[self setFloatValue: _floatValue knobProportion: _pendingKnobProportion]; [self setKnobProportion: _pendingKnobProportion];
_pendingKnobProportion = 0.0;
} }
else else
{ {
@ -751,7 +830,7 @@ static const float buttonsOffset = 2; // buttonsWidth = sw - buttonsOffset
NSPoint point; NSPoint point;
float lastPosition; float lastPosition;
float newPosition; float newPosition;
float floatValue; double doubleValue;
float offset; float offset;
float initialOffset; float initialOffset;
NSEvent *presentEvent = theEvent; NSEvent *presentEvent = theEvent;
@ -762,7 +841,7 @@ static const float buttonsOffset = 2; // buttonsWidth = sw - buttonsOffset
knobRect = [self rectForPart: NSScrollerKnob]; knobRect = [self rectForPart: NSScrollerKnob];
point = [self convertPoint: [theEvent locationInWindow] fromView: nil]; point = [self convertPoint: [theEvent locationInWindow] fromView: nil];
if (_isHorizontal) if (_scFlags.isHorizontal)
{ {
lastPosition = NSMidX(knobRect); lastPosition = NSMidX(knobRect);
offset = lastPosition - point.x; offset = lastPosition - point.x;
@ -801,7 +880,7 @@ static const float buttonsOffset = 2; // buttonsWidth = sw - buttonsOffset
point = [self convertPoint: [presentEvent locationInWindow] point = [self convertPoint: [presentEvent locationInWindow]
fromView: nil]; fromView: nil];
if (_isHorizontal) if (_scFlags.isHorizontal)
newPosition = point.x + offset; newPosition = point.x + offset;
else else
newPosition = point.y + offset; newPosition = point.y + offset;
@ -823,13 +902,13 @@ static const float buttonsOffset = 2; // buttonsWidth = sw - buttonsOffset
offset = initialOffset; offset = initialOffset;
} }
// only one coordinate (X or Y) is used to compute floatValue. // only one coordinate (X or Y) is used to compute doubleValue.
point = NSMakePoint(newPosition, newPosition); point = NSMakePoint(newPosition, newPosition);
floatValue = [self _floatValueForMousePoint: point]; doubleValue = [self _doubleValueForMousePoint: point];
if (floatValue != _floatValue) if (doubleValue != _doubleValue)
{ {
[self setFloatValue: floatValue]; [self setDoubleValue: doubleValue];
[self sendAction: _action to: _target]; [self sendAction: _action to: _target];
} }
@ -855,15 +934,11 @@ static const float buttonsOffset = 2; // buttonsWidth = sw - buttonsOffset
- (void) trackScrollButtons: (NSEvent*)theEvent - (void) trackScrollButtons: (NSEvent*)theEvent
{ {
id theCell = nil; id theCell = nil;
NSRect rect;
[self lockFocus];
NSDebugLog (@"trackScrollButtons"); NSDebugLog (@"trackScrollButtons");
_hitPart = [self testPart: [theEvent locationInWindow]]; _hitPart = [self testPart: [theEvent locationInWindow]];
rect = [self rectForPart: _hitPart];
/* /*
* A hit on a scroller button should be a page movement * A hit on a scroller button should be a page movement
@ -878,7 +953,7 @@ static const float buttonsOffset = 2; // buttonsWidth = sw - buttonsOffset
} }
/* Fall through to next case */ /* Fall through to next case */
case NSScrollerIncrementPage: case NSScrollerIncrementPage:
theCell = (_isHorizontal ? rightCell : downCell); theCell = (_scFlags.isHorizontal ? rightCell : downCell);
break; break;
case NSScrollerDecrementLine: case NSScrollerDecrementLine:
@ -888,7 +963,7 @@ static const float buttonsOffset = 2; // buttonsWidth = sw - buttonsOffset
} }
/* Fall through to next case */ /* Fall through to next case */
case NSScrollerDecrementPage: case NSScrollerDecrementPage:
theCell = (_isHorizontal ? leftCell : upCell); theCell = (_scFlags.isHorizontal ? leftCell : upCell);
break; break;
default: default:
@ -902,6 +977,10 @@ static const float buttonsOffset = 2; // buttonsWidth = sw - buttonsOffset
*/ */
if (theCell) if (theCell)
{ {
NSRect rect = [self rectForPart: _hitPart];
[self lockFocus];
[theCell highlight: YES withFrame: rect inView: self]; [theCell highlight: YES withFrame: rect inView: self];
[_window flushWindow]; [_window flushWindow];
@ -918,8 +997,9 @@ static const float buttonsOffset = 2; // buttonsWidth = sw - buttonsOffset
[theCell highlight: NO withFrame: rect inView: self]; [theCell highlight: NO withFrame: rect inView: self];
[_window flushWindow]; [_window flushWindow];
[self unlockFocus];
} }
[self unlockFocus];
NSDebugLog (@"return from trackScrollButtons"); NSDebugLog (@"return from trackScrollButtons");
} }
@ -929,21 +1009,13 @@ static const float buttonsOffset = 2; // buttonsWidth = sw - buttonsOffset
*/ */
- (void) drawRect: (NSRect)rect - (void) drawRect: (NSRect)rect
{ {
static NSRect rectForPartIncrementLine; NSRect rectForPartIncrementLine;
static NSRect rectForPartDecrementLine; NSRect rectForPartDecrementLine;
static NSRect rectForPartKnobSlot; NSRect rectForPartKnobSlot;
if (upCell == nil) rectForPartIncrementLine = [self rectForPart: NSScrollerIncrementLine];
{ rectForPartDecrementLine = [self rectForPart: NSScrollerDecrementLine];
[self drawParts]; rectForPartKnobSlot = [self rectForPart: NSScrollerKnobSlot];
[self checkSpaceForParts];
}
if (_cacheValid == NO)
{
rectForPartIncrementLine = [self rectForPart: NSScrollerIncrementLine];
rectForPartDecrementLine = [self rectForPart: NSScrollerDecrementLine];
rectForPartKnobSlot = [self rectForPart: NSScrollerKnobSlot];
}
[[_window backgroundColor] set]; [[_window backgroundColor] set];
NSRectFill (rect); NSRectFill (rect);
@ -956,11 +1028,13 @@ static const float buttonsOffset = 2; // buttonsWidth = sw - buttonsOffset
if (NSIntersectsRect (rect, rectForPartDecrementLine) == YES) if (NSIntersectsRect (rect, rectForPartDecrementLine) == YES)
{ {
[self drawArrow: NSScrollerDecrementArrow highlight: NO]; [self drawArrow: NSScrollerDecrementArrow
highlight: _hitPart == NSScrollerDecrementLine];
} }
if (NSIntersectsRect (rect, rectForPartIncrementLine) == YES) if (NSIntersectsRect (rect, rectForPartIncrementLine) == YES)
{ {
[self drawArrow: NSScrollerIncrementArrow highlight: NO]; [self drawArrow: NSScrollerIncrementArrow
highlight: _hitPart == NSScrollerIncrementLine];
} }
} }
@ -988,10 +1062,10 @@ static const float buttonsOffset = 2; // buttonsWidth = sw - buttonsOffset
switch (whichButton) switch (whichButton)
{ {
case NSScrollerDecrementArrow: case NSScrollerDecrementArrow:
theCell = (_isHorizontal ? leftCell : upCell); theCell = (_scFlags.isHorizontal ? leftCell : upCell);
break; break;
case NSScrollerIncrementArrow: case NSScrollerIncrementArrow:
theCell = (_isHorizontal ? rightCell : downCell); theCell = (_scFlags.isHorizontal ? rightCell : downCell);
break; break;
} }
@ -1008,7 +1082,7 @@ static const float buttonsOffset = 2; // buttonsWidth = sw - buttonsOffset
[self drawParts]; [self drawParts];
[self checkSpaceForParts]; [self checkSpaceForParts];
} }
if (_isHorizontal) if (_scFlags.isHorizontal)
[horizontalKnobCell drawWithFrame: [self rectForPart: NSScrollerKnob] [horizontalKnobCell drawWithFrame: [self rectForPart: NSScrollerKnob]
inView: self]; inView: self];
else else
@ -1018,22 +1092,29 @@ static const float buttonsOffset = 2; // buttonsWidth = sw - buttonsOffset
- (void) drawKnobSlot - (void) drawKnobSlot
{ {
static NSRect rect; [self drawKnobSlotInRect: [self rectForPart: NSScrollerKnobSlot]
highlight: NO];
}
- (void) drawKnobSlotInRect: (NSRect)slotRect highlight: (BOOL)flag
{
// FIXME: Not sure whether this method does the right thing
if (upCell == nil) if (upCell == nil)
{ {
[self drawParts]; [self drawParts];
[self checkSpaceForParts]; [self checkSpaceForParts];
} }
if (_cacheValid == NO) if (_scFlags.isHorizontal)
{ {
rect = [self rectForPart: NSScrollerKnobSlot]; [horizontalKnobSlotCell setHighlighted: flag];
[horizontalKnobSlotCell drawWithFrame: slotRect inView: self];
} }
if (_isHorizontal)
[horizontalKnobSlotCell drawWithFrame: rect inView: self];
else else
[verticalKnobSlotCell drawWithFrame: rect inView: self]; {
[verticalKnobSlotCell setHighlighted: flag];
[verticalKnobSlotCell drawWithFrame: slotRect inView: self];
}
} }
/**<p>Highlights the button whose under the mouse. Does nothing if the mouse /**<p>Highlights the button whose under the mouse. Does nothing if the mouse
@ -1096,7 +1177,7 @@ static const float buttonsOffset = 2; // buttonsWidth = sw - buttonsOffset
* If the scroller is disabled then the scroller buttons and the * If the scroller is disabled then the scroller buttons and the
* knob are not displayed at all. * knob are not displayed at all.
*/ */
if (!_isEnabled) if (!_scFlags.isEnabled)
{ {
usableParts = NSNoScrollerParts; usableParts = NSNoScrollerParts;
} }
@ -1111,7 +1192,7 @@ static const float buttonsOffset = 2; // buttonsWidth = sw - buttonsOffset
* of its orientation. * of its orientation.
* but keeps track of the scroller's orientation. * but keeps track of the scroller's orientation.
*/ */
if (_isHorizontal) if (_scFlags.isHorizontal)
{ {
width = scrollerFrame.size.height - 2; width = scrollerFrame.size.height - 2;
height = scrollerFrame.size.width - 2; height = scrollerFrame.size.width - 2;
@ -1148,9 +1229,7 @@ static const float buttonsOffset = 2; // buttonsWidth = sw - buttonsOffset
knobHeight = buttonsWidth; knobHeight = buttonsWidth;
/* calc knob's position */ /* calc knob's position */
knobPosition = _floatValue * (slotHeight - knobHeight); knobPosition = floor((float)_doubleValue * (slotHeight - knobHeight));
knobPosition = floor(knobPosition);
/* calc actual position */ /* calc actual position */
if (interfaceStyle == NSNextStepInterfaceStyle if (interfaceStyle == NSNextStepInterfaceStyle
@ -1245,7 +1324,7 @@ static const float buttonsOffset = 2; // buttonsWidth = sw - buttonsOffset
return NSZeroRect; return NSZeroRect;
} }
if (_isHorizontal) if (_scFlags.isHorizontal)
{ {
return NSMakeRect (y, x, height, width); return NSMakeRect (y, x, height, width);
} }
@ -1255,32 +1334,32 @@ static const float buttonsOffset = 2; // buttonsWidth = sw - buttonsOffset
} }
} }
+ (float) scrollerWidthForControlSize: (NSControlSize)controlSize
{
// FIXME
return [self scrollerWidth];
}
- (void) setControlSize: (NSControlSize)controlSize - (void) setControlSize: (NSControlSize)controlSize
{ {
// FIXME if (_scFlags.control_size == controlSize)
return;
_scFlags.control_size = controlSize;
[self setNeedsDisplay: YES];
} }
- (NSControlSize) controlSize - (NSControlSize) controlSize
{ {
// FIXME return _scFlags.control_size;
return NSRegularControlSize;
} }
- (void) setControlTint: (NSControlTint)controlTint - (void) setControlTint: (NSControlTint)controlTint
{ {
// FIXME if (_scFlags.control_tint == controlTint)
return;
_scFlags.control_tint = controlTint;
[self setNeedsDisplay: YES];
} }
- (NSControlTint) controlTint - (NSControlTint) controlTint
{ {
// FIXME return _scFlags.control_tint;
return NSDefaultControlTint;
} }
@end @end