diff --git a/AppKit/CPTextView/CPRulerMarker.j b/AppKit/CPTextView/CPRulerMarker.j index ea834658b..17d7360e8 100644 --- a/AppKit/CPTextView/CPRulerMarker.j +++ b/AppKit/CPTextView/CPRulerMarker.j @@ -37,7 +37,7 @@ Distance, in points, that the pointer must move beyond the ruler before a removable marker is removed when it is released. */ -var CPRulerMarkerRemovalDistance = 16.0; +var CPRulerMarkerRemovalDistance = 0.0; /*! @ingroup appkit @@ -66,6 +66,8 @@ var CPRulerMarkerRemovalDistance = 16.0; float _trackingStartLocation; float _trackingStartPoint; + float _trackingStartCrossPoint; + float _trackingCrossOffset; BOOL _trackingIsAdding; BOOL _trackingMoved; } @@ -164,10 +166,13 @@ var CPRulerMarkerRemovalDistance = 16.0; baseline = [_ruler baselineLocation]; // Whole-point positions keep every marker image sharp and identical, wherever it lies on the ruler. - if ([_ruler orientation] === CPHorizontalRuler) - return CGRectMake(ROUND(point - _imageOrigin.x), ROUND(baseline - _imageOrigin.y), imageSize.width, imageSize.height); + // While the user drags the marker outward, it follows the pointer across the ruler. + var crossPosition = baseline + (_isDragging ? _trackingCrossOffset : 0.0); - return CGRectMake(ROUND(baseline - _imageOrigin.x), ROUND(point - _imageOrigin.y), imageSize.width, imageSize.height); + if ([_ruler orientation] === CPHorizontalRuler) + return CGRectMake(ROUND(point - _imageOrigin.x), ROUND(crossPosition - _imageOrigin.y), imageSize.width, imageSize.height); + + return CGRectMake(ROUND(crossPosition - _imageOrigin.x), ROUND(point - _imageOrigin.y), imageSize.width, imageSize.height); } /*! @@ -286,7 +291,9 @@ var CPRulerMarkerRemovalDistance = 16.0; CGContextSaveGState(context); - if (_isOffRuler) + // Off the ruler's outer edge the marker follows the pointer and is clipped by the ruler. + // Off its inner edge it stays on its line, so it is drawn faded instead. + if (_isOffRuler && _trackingCrossOffset === 0.0) CGContextSetAlpha(context, 0.4); CGContextDrawImage(context, imageRect, _image); @@ -320,6 +327,8 @@ var CPRulerMarkerRemovalDistance = 16.0; _trackingMoved = NO; _trackingStartLocation = _markerLocation; _trackingStartPoint = [self _axisPointForEvent:anEvent]; + _trackingStartCrossPoint = [self _crossPointForEvent:anEvent]; + _trackingCrossOffset = 0.0; _isDragging = YES; _isOffRuler = NO; @@ -351,6 +360,10 @@ var CPRulerMarkerRemovalDistance = 16.0; _trackingMoved = YES; _isOffRuler = [self _isEventOffRuler:anEvent] && (_trackingIsAdding || _isRemovable); + // As in Cocoa, the marker stays on its line while the pointer is on the ruler, and follows + // the pointer out over the ruler's outer edge, where the ruler clips it. + _trackingCrossOffset = (_trackingIsAdding || _isRemovable) ? MIN(0.0, [self _crossPointForEvent:anEvent] - _trackingStartCrossPoint) : 0.0; + if (_trackingIsAdding || _isMovable) { var proposedLocation = _trackingStartLocation + [self _axisPointForEvent:anEvent] - _trackingStartPoint; @@ -376,6 +389,8 @@ var CPRulerMarkerRemovalDistance = 16.0; var wasOffRuler = _isOffRuler; + _trackingCrossOffset = 0.0; + _isDragging = NO; _isOffRuler = NO; @@ -406,6 +421,14 @@ var CPRulerMarkerRemovalDistance = 16.0; [_ruler setNeedsDisplay:YES]; } +/* @ignore */ +- (float)_crossPointForEvent:(CPEvent)anEvent +{ + var point = [_ruler convertPoint:[anEvent locationInWindow] fromView:nil]; + + return [_ruler orientation] === CPHorizontalRuler ? point.y : point.x; +} + /* @ignore */ - (float)_axisPointForEvent:(CPEvent)anEvent { diff --git a/Tests/Manual/TextEditor/WORKLIST.md b/Tests/Manual/TextEditor/WORKLIST.md index 003f57b33..56ac2b07c 100644 --- a/Tests/Manual/TextEditor/WORKLIST.md +++ b/Tests/Manual/TextEditor/WORKLIST.md @@ -24,6 +24,10 @@ TextEditor is a document-based test application and a tutorial. When the app use - **Images in text.** AppKit has no general `CPTextAttachment` class, only the table attachment `_CPTableTextAttachment`. The RTF parser and producer do not handle `\pict`. - **Lists.** There is no `CPTextList`, and `CPParagraphStyle` has no `textLists`. +### Ruler + +- **Marker appearance and vertical alignment differ from TextEdit.** The marker images, and where markers sit across the ruler, are interim until Aristo3 supplies its own; adjust them to match TextEdit then. A tab stop dragged up off the ruler follows the pointer and is clipped by the ruler's edge, as in TextEdit. Dragged down off the ruler, it stays on its line and is drawn faded until release; TextEdit's behaviour in that direction has not been checked. + ### nib2cib - **nib2cib ignores the ruler settings.** The "Uses Ruler" setting in Interface Builder does not reach the cib. `CPTextView` and `CPRulerView` also need to archive their ruler settings.