@@ -286,8 +286,13 @@ - (void)mouseDragged:(NSEvent *)theEvent
286286
287287- (void ) handleMouseEvent : (NSEvent *)theEvent
288288{
289- NSPoint locationInSelf = [self convertPoint: theEvent.locationInWindow fromView: nil ];
289+ static BOOL isDragging;
290+ static dispatch_once_t onceToken;
291+ dispatch_once (&onceToken, ^{
292+ isDragging = NO ;
293+ });
290294
295+ NSPoint locationInSelf = [self convertPoint: theEvent.locationInWindow fromView: nil ];
291296 NSSize textSize = [self .textView.layoutManager usedRectForTextContainer: self .textView.textContainer].size ;
292297 NSSize frameSize = self.frame .size ;
293298
@@ -299,17 +304,43 @@ - (void) handleMouseEvent:(NSEvent *)theEvent
299304 point = NSMakePoint (locationInSelf.x / textSize.width , locationInSelf.y / frameSize.height );
300305 }
301306
302- [self goAtRelativePosition: point];
307+ BOOL justStartDragging = NO ;
308+ if (theEvent.type == NSLeftMouseUp ) {
309+ isDragging = NO ;
310+ }
311+ else {
312+ justStartDragging = !isDragging;
313+ isDragging = YES ;
314+ }
315+
316+ [self goAtRelativePosition: point justStartDragging: justStartDragging];
303317}
304318
305- - (void )goAtRelativePosition : (NSPoint )position
319+ - (void )goAtRelativePosition : (NSPoint )position justStartDragging : ( BOOL ) justStartDragging
306320{
321+ static CGFloat mouseDownOffset;
322+ static dispatch_once_t onceToken;
323+ dispatch_once (&onceToken, ^{
324+ mouseDownOffset = 0 ;
325+ });
326+
307327 CGFloat documentHeight = [self .editorScrollView.documentView frame ].size .height ;
308328 CGSize boundsSize = self.editorScrollView .bounds .size ;
309329 CGFloat maxOffset = documentHeight - boundsSize.height ;
330+ CGFloat locationInDocumentY = documentHeight * position.y ;
310331
311- CGFloat offset = floor (documentHeight * position.y - boundsSize.height /2 );
332+ if (justStartDragging) {
333+ mouseDownOffset = locationInDocumentY -
334+ (self.editorScrollView .contentView .documentVisibleRect .origin .y + boundsSize.height /2.0 );
335+ }
312336
337+ CGFloat offset;
338+ if (fabs (mouseDownOffset) <= boundsSize.height /2.0 ) {
339+ offset = floor (locationInDocumentY - boundsSize.height /2 - mouseDownOffset);
340+ }
341+ else {
342+ offset = floor (locationInDocumentY - boundsSize.height /2 );
343+ }
313344 offset = MIN (MAX (0 , offset), maxOffset);
314345
315346 [self .editorTextView scrollRectToVisible: NSMakeRect (0 , offset, boundsSize.width, boundsSize.height)];
0 commit comments