Make NSScroller understand alt key.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@4370 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 1999-06-06 08:19:19 +00:00
parent ea1da7506d
commit 7a0c72a800
3 changed files with 182 additions and 124 deletions

View file

@ -1,3 +1,8 @@
Sun Jun 6 9:35:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
* Source/NSScrollView.m: tidyup
* Source/NSScroller.m: Permit use of alt key to slow down scrolling.
Sat Jun 5 21:50:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
Added image updates by jagapen@whitewater.chem.wisc.edu -

View file

@ -39,14 +39,14 @@
@implementation NSScrollView
//
// Class variables
//
/*
* Class variables
*/
static Class rulerViewClass = nil;
//
// Class methods
//
/*
* Class methods
*/
+ (void) initialize
{
if (self == [NSScrollView class])
@ -73,9 +73,11 @@ static Class rulerViewClass = nil;
{
NSSize size = frameSize;
// Substract 1 from the width and height of
// the line that separates the horizontal
// and vertical scroller from the clip view
/*
* Substract 1 from the width and height of
* the line that separates the horizontal
* and vertical scroller from the clip view
*/
if (hFlag)
{
size.height -= [NSScroller scrollerWidth];
@ -114,9 +116,10 @@ static Class rulerViewClass = nil;
{
NSSize size = contentSize;
// Add 1 to the width and height for the
// line that separates the horizontal and
// vertical scroller from the clip view.
/*
* Add 1 to the width and height for the line that separates the
* horizontal and vertical scroller from the clip view.
*/
if (hFlag)
{
size.height += [NSScroller scrollerWidth];
@ -148,13 +151,13 @@ static Class rulerViewClass = nil;
return size;
}
//
// Instance methods
//
/*
* Instance methods
*/
- (id) initWithFrame: (NSRect)rect
{
[super initWithFrame: rect];
[self setContentView: [[NSClipView new] autorelease]];
[self setContentView: AUTORELEASE([NSClipView new])];
_lineScroll = 10;
_pageScroll = 10;
_borderType = NSBezelBorder;
@ -171,12 +174,12 @@ static Class rulerViewClass = nil;
- (void) dealloc
{
[_contentView release];
TEST_RELEASE(_contentView);
[_horizScroller release];
[_vertScroller release];
[_horizRuler release];
[_vertRuler release];
TEST_RELEASE(_horizScroller);
TEST_RELEASE(_vertScroller);
TEST_RELEASE(_horizRuler);
TEST_RELEASE(_vertRuler);
[super dealloc];
}
@ -198,8 +201,10 @@ static Class rulerViewClass = nil;
{
[_horizScroller removeFromSuperview];
// Do not add the scroller view to the subviews array yet;
// -setHasHorizontalScroller must be invoked first
/*
* Do not add the scroller view to the subviews array yet;
* -setHasHorizontalScroller must be invoked first
*/
ASSIGN(_horizScroller, aScroller);
if (_horizScroller)
{
@ -219,7 +224,7 @@ static Class rulerViewClass = nil;
if (_hasHorizScroller)
{
if (!_horizScroller)
[self setHorizontalScroller: [[NSScroller new] autorelease]];
[self setHorizontalScroller: AUTORELEASE([NSScroller new])];
[self addSubview: _horizScroller];
}
else
@ -232,8 +237,10 @@ static Class rulerViewClass = nil;
{
[_vertScroller removeFromSuperview];
// Do not add the scroller view to the subviews array yet;
// -setHasVerticalScroller must be invoked first
/*
* Do not add the scroller view to the subviews array yet;
* -setHasVerticalScroller must be invoked first
*/
ASSIGN(_vertScroller, aScroller);
if (_vertScroller)
{
@ -254,7 +261,7 @@ static Class rulerViewClass = nil;
{
if (!_vertScroller)
{
[self setVerticalScroller: [[NSScroller new] autorelease]];
[self setVerticalScroller: AUTORELEASE([NSScroller new])];
if (_contentView && !_contentView->_rFlags.flipped_view)
[_vertScroller setFloatValue: 1];
}
@ -268,16 +275,16 @@ static Class rulerViewClass = nil;
- (void) _doScroll: (NSScroller*)scroller
{
float floatValue = [scroller floatValue];
NSRect clipViewBounds = [_contentView bounds];
float floatValue = [scroller floatValue];
NSRect clipViewBounds = [_contentView bounds];
NSScrollerPart hitPart = [scroller hitPart];
NSRect documentRect = [_contentView documentRect];
float amount = 0;
NSPoint point = clipViewBounds.origin;
NSRect documentRect = [_contentView documentRect];
float amount = 0;
NSPoint point = clipViewBounds.origin;
NSDebugLog (@"_doScroll: float value = %f", floatValue);
// do nothing if scroller is unknown
/* do nothing if scroller is unknown */
if (scroller != _horizScroller && scroller != _vertScroller)
return;
@ -301,7 +308,7 @@ static Class rulerViewClass = nil;
return;
}
if (!_knobMoved) // button scrolling
if (!_knobMoved) /* button scrolling */
{
if (scroller == _horizScroller)
{
@ -311,8 +318,7 @@ static Class rulerViewClass = nil;
{
if (!_contentView->_rFlags.flipped_view)
{
// If view is flipped
// reverse the scroll direction
/* If view is flipped reverse the scroll direction */
amount = -amount;
}
NSDebugLog (@"increment/decrement: amount = %f, flipped = %d",
@ -320,7 +326,7 @@ static Class rulerViewClass = nil;
point.y = clipViewBounds.origin.y + amount;
}
}
else // knob scolling
else /* knob scolling */
{
if (scroller == _horizScroller)
{
@ -394,12 +400,12 @@ static Class rulerViewClass = nil;
}
}
- (void) setHorizontalRulerView: (NSRulerView*)aRulerView // FIX ME
- (void) setHorizontalRulerView: (NSRulerView*)aRulerView // FIX ME
{
ASSIGN(_horizRuler, aRulerView);
}
- (void) setHasHorizontalRuler: (BOOL)flag // FIX ME
- (void) setHasHorizontalRuler: (BOOL)flag // FIX ME
{
if (_hasHorizRuler == flag)
return;
@ -407,12 +413,12 @@ static Class rulerViewClass = nil;
_hasHorizRuler = flag;
}
- (void) setVerticalRulerView: (NSRulerView*)ruler // FIX ME
- (void) setVerticalRulerView: (NSRulerView*)ruler // FIX ME
{
ASSIGN(_vertRuler, ruler);
}
- (void) setHasVerticalRuler: (BOOL)flag // FIX ME
- (void) setHasVerticalRuler: (BOOL)flag // FIX ME
{
if (_hasVertRuler == flag)
return;
@ -497,11 +503,7 @@ static Class rulerViewClass = nil;
[_horizScroller setFrame: horizScrollerRect];
[_vertScroller setFrame: vertScrollerRect];
[_contentView setFrame: contentRect];
#if 1
// [_contentView viewFrameChanged: nil];
// update scroller
[self reflectScrolledClipView: (NSClipView*)_contentView];
#endif
}
- (void) drawRect: (NSRect)rect
@ -511,11 +513,6 @@ static Class rulerViewClass = nil;
float horizLinePosition, horizLineLength = [self bounds].size.width;
float borderThickness = 0;
// fprintf (stderr,
// "NSScrollView drawRect: origin (%1.2f, %1.2f), size (%1.2f, %1.2f)\n",
// rect.origin.x, rect.origin.y,
// rect.size.width, rect.size.height);
DPSgsave(ctxt);
switch ([self borderType])
{

View file

@ -46,13 +46,15 @@
@implementation NSScroller
//
// Class variables
//
static NSButtonCell* upCell = nil; // button cells used by
static NSButtonCell* downCell = nil; // scroller instances
static NSButtonCell* leftCell = nil; // to draw scroller
static NSButtonCell* rightCell = nil; // buttons and knob.
/*
* 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;
static NSButtonCell* knobCell = nil;
static const float scrollerWidth = 18;
@ -69,9 +71,9 @@ static float slotWidthMinusKnobWidth;
static NSRect slotRect = {{0,0},{0,0}};
static BOOL preCalcValues = NO;
//
// Class methods
//
/*
* Class methods
*/
+ (void) initialize
{
if (self == [NSScroller class])
@ -154,7 +156,9 @@ static BOOL preCalcValues = NO;
- (id) initWithFrame: (NSRect)frameRect
{
// determine the orientation of the scroller and adjust it's size accordingly
/*
* determine the orientation of the scroller and adjust it's size accordingly
*/
if (frameRect.size.width > frameRect.size.height)
{
_isHorizontal = YES;
@ -194,7 +198,9 @@ static BOOL preCalcValues = NO;
- (void) drawParts
{
// Create the class variable button cells if they do not yet exist.
/*
* Create the class variable button cells if they do not yet exist.
*/
if (knobCell)
return;
@ -322,7 +328,9 @@ static BOOL preCalcValues = NO;
- (void) setFrame: (NSRect)frameRect
{
// determine the orientation of the scroller and adjust it's size accordingly
/*
* determine the orientation of the scroller and adjust it's size accordingly
*/
if (frameRect.size.width > frameRect.size.height)
{
_isHorizontal = YES;
@ -354,7 +362,9 @@ static BOOL preCalcValues = NO;
- (NSScrollerPart)testPart: (NSPoint)thePoint
{
// return what part of the scroller the mouse hit
/*
* return what part of the scroller the mouse hit
*/
NSRect rect;
if (thePoint.x <= 0 || thePoint.x >= frame.size.width
@ -395,7 +405,9 @@ static BOOL preCalcValues = NO;
float floatValue = 0;
float position;
// Adjust point to lie within the knob slot
/*
* Adjust point to lie within the knob slot
*/
if (_isHorizontal)
{
float halfKnobRectWidth = knobRect.size.width / 2;
@ -411,7 +423,9 @@ static BOOL preCalcValues = NO;
else
position = point.x;
}
// Compute float value given the knob size
/*
* Compute float value given the knob size
*/
floatValue = (position - (slotRect.origin.x + halfKnobRectWidth))
/ (slotRect.size.width - knobRect.size.width);
}
@ -430,7 +444,9 @@ static BOOL preCalcValues = NO;
else
position = point.y;
}
// Compute float value given the knob size
/*
* Compute float value given the knob size
*/
floatValue = (position - (slotRect.origin.y + halfKnobRectHeight)) /
(slotRect.size.height - knobRect.size.height);
}
@ -537,18 +553,20 @@ static BOOL preCalcValues = NO;
unsigned int eventMask = NSLeftMouseDownMask | NSLeftMouseUpMask
| NSLeftMouseDraggedMask | NSMouseMovedMask
| NSPeriodicMask;
NSApplication *app = [NSApplication sharedApplication];
NSPoint point, apoint;
float oldFloatValue = _floatValue;
float floatValue;
float xoffset = 0;
float yoffset = 0;
NSDate *theDistantFuture = [NSDate distantFuture];
NSEventType eventType;
NSRect knobRect = {{0,0},{0,0}};
int periodCount = 0; // allows a forced update
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]; // pre calc scroller parts
[self _preCalcParts];
preCalcValues = YES;
knobRect = [self rectForPart: NSScrollerKnob];
@ -574,7 +592,9 @@ static BOOL preCalcValues = NO;
}
_hitPart = NSScrollerKnob;
// set periodic events rate to achieve max of ~30fps
/*
* set periodic events rate to achieve max of ~30fps
*/
[NSEvent startPeriodicEventsAfterDelay: 0.02 withPeriod: 0.03];
[[NSRunLoop currentRunLoop] limitDateForMode: NSEventTrackingRunLoopMode];
@ -583,15 +603,20 @@ static BOOL preCalcValues = NO;
if (eventType != NSPeriodic)
{
apoint = [theEvent locationInWindow];
// zero the periodic count whenever a real position event is received
flags = [theEvent modifierFlags];
periodCount = 0;
}
else
{
// if 6x periods have gone by w/o movement
// check mouse and update if necessary
/*
* if 6x periods have gone by w/o movement
* check mouse and update if necessary
*/
if (periodCount == 6)
apoint = [window mouseLocationOutsideOfEventStream];
{
apoint = [window mouseLocationOutsideOfEventStream];
periodCount = 0;
}
point = [self convertPoint: apoint fromView: nil];
point.x += xoffset;
@ -599,6 +624,24 @@ static BOOL preCalcValues = NO;
if (point.x != knobRect.origin.x || point.y != knobRect.origin.y)
{
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;
}
floatValue = [self _floatValueForMousePointFromPreCalc: point];
if (floatValue != oldFloatValue)
@ -615,16 +658,18 @@ static BOOL preCalcValues = NO;
}
knobRect.origin = point;
}
// 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
/*
* 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
*/
periodCount++;
}
theEvent = [app nextEventMatchingMask: eventMask
untilDate: theDistantFuture
inMode: NSEventTrackingRunLoopMode
dequeue: YES];
theEvent = [NSApp nextEventMatchingMask: eventMask
untilDate: theDistantFuture
inMode: NSEventTrackingRunLoopMode
dequeue: YES];
}
[NSEvent stopPeriodicEvents];
@ -633,13 +678,13 @@ static BOOL preCalcValues = NO;
- (void) trackScrollButtons: (NSEvent*)theEvent
{
NSApplication *theApp = [NSApplication sharedApplication];
unsigned int eventMask = NSLeftMouseDownMask | NSLeftMouseUpMask |
NSApplication *theApp = [NSApplication sharedApplication];
unsigned int eventMask = NSLeftMouseDownMask | NSLeftMouseUpMask |
NSLeftMouseDraggedMask | NSMouseMovedMask;
NSPoint location;
BOOL shouldReturn = NO;
id theCell = nil;
NSRect rect;
NSPoint location;
BOOL shouldReturn = NO;
id theCell = nil;
NSRect rect;
NSDebugLog (@"trackScrollButtons");
do
@ -698,9 +743,9 @@ static BOOL preCalcValues = NO;
NSDebugLog (@"return from trackScrollButtons");
}
//
// draw the scroller
//
/*
* draw the scroller
*/
- (void) drawRect: (NSRect)rect
{
NSDebugLog (@"NSScroller drawRect: ((%f, %f), (%f, %f))",
@ -745,7 +790,9 @@ static BOOL preCalcValues = NO;
{
NSRect rect;
// in a modal loop we have already pre calc'd our parts
/*
* in a modal loop we have already pre calc'd our parts
*/
if (preCalcValues)
rect = slotRect;
else
@ -769,7 +816,7 @@ static BOOL preCalcValues = NO;
[self drawArrow: NSScrollerDecrementArrow highlight: flag];
break;
default: // No button currently hit for highlighting.
default: /* No button currently hit for highlighting. */
break;
}
}
@ -781,17 +828,21 @@ static BOOL preCalcValues = NO;
float width, height;
float buttonsSize = 2 * buttonsWidth + 2;
NSUsableScrollerParts usableParts;
// If the scroller is disabled then the scroller buttons and the
// knob are not displayed at all.
/*
* If the scroller is disabled then the scroller buttons and the
* knob are not displayed at all.
*/
if (!_isEnabled)
usableParts = NSNoScrollerParts;
else
usableParts = _usableParts;
// 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.
/*
* 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.
*/
if (_isHorizontal)
{
width = scrollerFrame.size.height - 2;
@ -803,39 +854,45 @@ static BOOL preCalcValues = NO;
height = scrollerFrame.size.height - 2;
}
// 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.
/*
* 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.
*/
switch (partCode)
{
case NSScrollerKnob:
{
float knobHeight, knobPosition, slotHeight;
// If the scroller does not have parts or a knob return a zero rect.
if (usableParts == NSNoScrollerParts ||
usableParts == NSOnlyScrollerArrows)
if (usableParts == NSNoScrollerParts
|| usableParts == NSOnlyScrollerArrows)
return NSZeroRect;
// calc the slot Height
slotHeight = height - (_arrowsPosition == NSScrollerArrowsNone ?
0 : buttonsSize);
/* calc the slot Height */
slotHeight = height - (_arrowsPosition == NSScrollerArrowsNone
? 0 : buttonsSize);
knobHeight = _knobProportion * slotHeight;
if (knobHeight < buttonsWidth)
knobHeight = buttonsWidth;
// calc knob's position
/* calc knob's position */
knobPosition = _floatValue * (slotHeight - knobHeight);
knobPosition = (float)floor(knobPosition); // avoid rounding error
// calc actual position
knobPosition = (float)floor(knobPosition);
/* calc actual position */
y += knobPosition + (_arrowsPosition == NSScrollerArrowsMaxEnd
|| _arrowsPosition == NSScrollerArrowsNone ?
0 : buttonsSize);
|| _arrowsPosition == NSScrollerArrowsNone ? 0 : buttonsSize);
height = knobHeight;
width = buttonsWidth;
break;
}
case NSScrollerKnobSlot:
// if the scroller does not have buttons the slot completely
// fills the scroller.
/*
* if the scroller does not have buttons the slot completely
* fills the scroller.
*/
if (usableParts == NSNoScrollerParts
|| _arrowsPosition == NSScrollerArrowsNone)
{
@ -850,7 +907,6 @@ static BOOL preCalcValues = NO;
case NSScrollerDecrementLine:
case NSScrollerDecrementPage:
// if scroller has no parts or knob then return a zero rect
if (usableParts == NSNoScrollerParts
|| _arrowsPosition == NSScrollerArrowsNone)
{