I have an NSScrollView with a custom NSImageView as a representation of its document installed in an xib file. My problem arises when I want to increase NSScrollView. I would like it to behave like a Preview application on a Mac, and I can get it to enlarge it, but I want it to grow using the cursor as a center point.
I have this code in my regular NSScrollView class:
- (void)magnifyWithEvent:(NSEvent *)event {
NSPoint conViewPoint =[[self contentView] convertPoint:[event locationInWindow] fromView:nil];
[self setMagnification:[event magnification]+[self magnification] centeredAtPoint:conViewPoint];
}
This works, however, it also forces the scroll to scroll down as it increases (although it does not move at all from the side). This is more noticeable when you repeatedly zoom in and out without raising it from the trackpad.
A similar problem seems to be in this question, however I use a pinch gesture, not a button. I tried to compensate for the y axis scrolling as suggested for this question using
[[self documentView] scrollPoint:scrollPoint]
but I could not calculate a working formula for scrollPoint, which takes into account the changing boundaries of the content view, in order to keep the point under the cursor in the same place. So, I am wondering if there is a more correct approach to this, or if scrolling is really necessary, and I just need to figure out the math.
Thanks for any help with this.
EDIT:
So, I finally figured out a math scroll. It took some time and more complicated attempts, but in the end it is quite simple:
- (void)magnifyWithEvent:(NSEvent *)event {
NSPoint docViewPoint =[[self documentView] convertPoint:[event locationInWindow] fromView:nil];
NSPoint docRectOri=[self documentVisibleRect].origin;
float widthGapSize=-docRectOri.x;
float heightGapSize=-docRectOri.y;
if([event phase]==NSEventPhaseBegan){
startDocPoint=docViewPoint;
startPoint.x=(docViewPoint.x+widthGapSize)*[self magnification];
startPoint.y=(docViewPoint.y+heightGapSize)*[self magnification];
}
scrollPoint.x=startDocPoint.x-(startPoint.x/[self magnification]);
scrollPoint.y=startDocPoint.y-(startPoint.y/[self magnification]);
[self setMagnification:[event magnification]+[self magnification] centeredAtPoint:docViewPoint];
[[self documentView] scrollPoint:scrollPoint];
}
, setMagnification:centeredAtPoint: , , - - , - .