Skip to content

Instantly share code, notes, and snippets.

@Kentzo
Created October 22, 2011 20:55
Show Gist options
  • Select an option

  • Save Kentzo/1306484 to your computer and use it in GitHub Desktop.

Select an option

Save Kentzo/1306484 to your computer and use it in GitHub Desktop.
Фантастический костыль для мапа между мониторами с разным PPI
- (NSRect)scaleWindowFrame:(NSRect)aFrame toView:(NSView *)aView
{
NSScreen *windowScreen = [self preferredScreen];
NSScreen *viewScreen = [[aView window] screen];
if (windowScreen == nil || viewScreen == nil)
return NSZeroRect;
NSRect screenFrameInViewCoordinates = [windowScreen visibleFrame];
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_6)
{
// Convert window screen coordinates to base coordinates of aView.
CGFloat viewScreenScaleFactor = [viewScreen userSpaceScaleFactor];
screenFrameInViewCoordinates = NSMakeRect(screenFrameInViewCoordinates.origin.x * viewScreenScaleFactor,
screenFrameInViewCoordinates.origin.y * viewScreenScaleFactor,
screenFrameInViewCoordinates.size.width * viewScreenScaleFactor,
screenFrameInViewCoordinates.size.height * viewScreenScaleFactor);
// Convert from base coordinates to view's coordinates.
screenFrameInViewCoordinates = [aView convertRectFromBase:screenFrameInViewCoordinates];
}
else
{
if ([windowScreen isEqual:viewScreen])
screenFrameInViewCoordinates = [aView convertRectFromBacking:[windowScreen convertRectToBacking:screenFrameInViewCoordinates]];
else
{
// Convert window screen coordinates to backing coordinates.
screenFrameInViewCoordinates = [windowScreen convertRectToBacking:screenFrameInViewCoordinates];
// Convert from window screen backing coordinates to aView backing coordinates.
CGFloat windowScaleFactor = [windowScreen backingScaleFactor];
CGFloat viewScaleFactor = [viewScreen backingScaleFactor];
CGFloat scaleFactor = viewScaleFactor / windowScaleFactor;
screenFrameInViewCoordinates = NSMakeRect(screenFrameInViewCoordinates.origin.x * scaleFactor,
screenFrameInViewCoordinates.origin.y * scaleFactor,
screenFrameInViewCoordinates.size.width * scaleFactor,
screenFrameInViewCoordinates.size.height * scaleFactor);
// Convert from backing coordinates to aView coordinates.
screenFrameInViewCoordinates = [viewScreen convertRectFromBacking:screenFrameInViewCoordinates];
}
}
NSRect viewBounds = [aView bounds];
NSPoint viewToScreenRatio = NSMakePoint(screenFrameInViewCoordinates.size.width / viewBounds.size.width,
screenFrameInViewCoordinates.size.height / viewBounds.size.height);
NSRect screenFrame = [windowScreen visibleFrame];
NSRect scaledWindowFrame = NSMakeRect(aFrame.origin.x / screenFrame.size.width * viewToScreenRatio.x,
aFrame.origin.y / screenFrame.size.height * viewToScreenRatio.y,
aFrame.size.width / screenFrame.size.width * viewToScreenRatio.x,
aFrame.size.height / screenFrame.size.height * viewToScreenRatio.y);
return [aView centerScanRect:scaledWindowFrame];
}
- (NSRect)scaleWindowFrame:(NSRect)aFrame fromView:(NSView *)aView
{
NSScreen *windowScreen = [self preferredScreen];
NSScreen *viewScreen = [[aView window] screen];
if (windowScreen == nil || viewScreen == nil)
return NSZeroRect;
NSRect viewBoundsInScreenCoordinates = [aView bounds];
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_6)
{
// Convert aView coordinates to base coordinates of aView.
viewBoundsInScreenCoordinates = [aView convertRectToBase:viewBoundsInScreenCoordinates];
// Convert base coordinates of aView to window screen coordinates
CGFloat viewScaleFactor = [viewScreen userSpaceScaleFactor];
viewBoundsInScreenCoordinates = NSMakeRect(viewBoundsInScreenCoordinates.origin.x / viewScaleFactor,
viewBoundsInScreenCoordinates.origin.y / viewScaleFactor,
viewBoundsInScreenCoordinates.size.width / viewScaleFactor,
viewBoundsInScreenCoordinates.size.height / viewScaleFactor);
}
else
{
if ([viewScreen isEqual:windowScreen])
viewBoundsInScreenCoordinates = [windowScreen convertRectFromBacking:[aView convertRectToBacking:viewBoundsInScreenCoordinates]];
else
{
// Convert aView coordinates to backing coordinates of aView.
viewBoundsInScreenCoordinates = [aView convertRectToBacking:viewBoundsInScreenCoordinates];
// Convert backing coordinates of aView to backing coordinates of window screen.
CGFloat windowScaleFactor = [windowScreen backingScaleFactor];
CGFloat viewScaleFactor = [viewScreen backingScaleFactor];
CGFloat scaleFactor = windowScaleFactor / viewScaleFactor;
viewBoundsInScreenCoordinates = NSMakeRect(viewBoundsInScreenCoordinates.origin.x * scaleFactor,
viewBoundsInScreenCoordinates.origin.y * scaleFactor,
viewBoundsInScreenCoordinates.size.width * scaleFactor,
viewBoundsInScreenCoordinates.size.height * scaleFactor);
// Convert from backing coordinates of window screen to window screen coordinates.
viewBoundsInScreenCoordinates = [windowScreen convertRectFromBacking:viewBoundsInScreenCoordinates];
}
}
NSRect screenFrame = [windowScreen visibleFrame];
NSPoint screenToViewRatio = NSMakePoint(viewBoundsInScreenCoordinates.size.width / screenFrame.size.width,
viewBoundsInScreenCoordinates.size.height / screenFrame.size.height);
NSRect viewBounds = [aView bounds];
NSRect scaledWindowFrame = NSMakeRect(aFrame.origin.x / viewBounds.size.width * screenToViewRatio.x,
aFrame.origin.y / viewBounds.size.height * screenToViewRatio.y,
aFrame.size.width / viewBounds.size.width * screenToViewRatio.x,
aFrame.size.height / viewBounds.size.height * screenToViewRatio.y);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment