How to convert the position in CGDisplayBounds() to global coordinate ( like NSEvent.mouseLocation) in Swift

huangapple go评论58阅读模式
英文:

How to convert the position in CGDisplayBounds() to global coordinate ( like NSEvent.mouseLocation) in Swift

问题

I'm a newbie in Swift and MacOS.
I gonna find a method to get the exact display coordinate

NSEvent.mouseLocation

How to convert the position in CGDisplayBounds() to global coordinate ( like NSEvent.mouseLocation) in Swift

I have found method in CoreGraphic :

func CGDisplayBounds(_ display: CGDirectDisplayID) -> CGRect

but the coordinate is different.

How to convert the position in CGDisplayBounds() to global coordinate ( like NSEvent.mouseLocation) in Swift

I can workaround to apply a method to mathematically method to convert point Y.
But is there any method to get or convert the position programmatically?

I expect to get the same coordinate with NSEvent.mouseLocation.

Thank for your attention.

It returns to the same coordinate with mouse location.

英文:

I'm a newbie in Swift and MacOS.
I gonna find a method to get the exact display coordinate

NSEvent.mouseLocation

How to convert the position in CGDisplayBounds() to global coordinate ( like NSEvent.mouseLocation) in Swift

I have found method in CoreGraphic :

func CGDisplayBounds(_ display: CGDirectDisplayID) -> CGRect

but the coordinate is different.

How to convert the position in CGDisplayBounds() to global coordinate ( like NSEvent.mouseLocation) in Swift

I can workaround to apply a method to mathematically method to convert point Y.
But is there any method to get or convert the position programmatically?

I expect to get the same coordinate with NSEvent.mouseLocation.

Thank for your attention.

It returns to the same coordinate with mouse location.

答案1

得分: 0

如您所指出,CoreGraphics 具有苹果所称的'翻转'几何结构,原点位于左上角,y 坐标朝屏幕底部增加。这是大多数计算机图形系统使用的几何结构。

AppKit 更喜欢苹果所称的'非翻转'几何结构,原点位于左下角,y 坐标朝屏幕顶部增加。这通常在数学中使用的几何结构。

CoreGraphics 全局几何的原点 (0, 0) 始终位于“主”显示的左上角(通过 CGMainDisplayID() 标识)。而 AppKit 全局几何的原点始终位于主显示的左下角。要在这两种几何结构之间转换,只需从主显示的高度中减去您的 y 坐标。

具体如下:

extension CGPoint {
    func convertedToAppKit() -> CGPoint {
        return .init(
            x: x,
            y: CGDisplayBounds(CGMainDisplayID()).height - y
        )
    }

    func convertedToCoreGraphics() -> CGPoint {
        return .init(
            x: x,
            y: CGDisplayBounds(CGMainDisplayID()).height - y
        )
    }
}

您可能会注意到这两个函数具有相同的实现。实际上,您不需要两个函数,只需使用一个函数即可进行双向转换。

调用 CGDisplayBounds(CGMainDisplayID()) 可能效率不高。如果您需要频繁执行此类转换,可能需要缓存该值或批量执行转换操作。但如果您缓存该值,还需要订阅 NSApplication.didChangeScreenParametersNotification,以便在需要时更新缓存的值。

英文:

As you noted, CoreGraphics has what Apple calls ‘flipped’ geometry, with the origin at the top left and the y coordinates increasing toward the bottom of the screen. This is the geometry used by most computer graphics systems.

AppKit prefers what Apple calls ‘non-flipped’, with the origin at the bottom left and the y coordinates increasing toward the top of the screen. This is the geometry normally used in mathematics.

The origin (0, 0) of the CoreGraphics global geometry is always at the top-left of the ‘main’ display (identified by CGMainDisplayID()). The origin of the AppKit global geometry is always at the bottom-left of the main display. To convert between the two geometries, subtract your y coordinate from the height of the main display.

That is:

extension CGPoint {
    func convertedToAppKit() -> CGPoint {
        return .init(
            x: x,
            y: CGDisplayBounds(CGMainDisplayID()).height - y
        )
    }

    func convertedToCoreGraphics() -> CGPoint {
        return .init(
            x: x,
            y: CGDisplayBounds(CGMainDisplayID()).height - y
        )
    }
}

You may notice that these two functions have the same implementation. You don't really need two functions; you can just use one. It converts in both directions.

Calling CGDisplayBounds(CGMainDisplayID()) might also be inefficient. You might want to cache the value or batch your transformations if you're going to be doing a lot of them. But if you cache the value, you'll want to subscribe to NSApplication.didChangeScreenParametersNotification so you can update the cached value if it needs to change.

huangapple
  • 本文由 发表于 2023年2月10日 10:11:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/75406300.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定