mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
213 lines
8.3 KiB
Swift
213 lines
8.3 KiB
Swift
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
|
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
|
//
|
|
// See https://swift.org/LICENSE.txt for license information
|
|
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
import Foundation
|
|
@_exported import AppKit
|
|
|
|
extension NSRect {
|
|
/// Fills this rect in the current NSGraphicsContext in the context's fill
|
|
/// color.
|
|
/// The compositing operation of the fill defaults to the context's
|
|
/// compositing operation, not necessarily using `.copy` like `NSRectFill()`.
|
|
/// - precondition: There must be a set current NSGraphicsContext.
|
|
@available(swift 4)
|
|
public func fill(using operation: NSCompositingOperation =
|
|
NSGraphicsContext.current?.compositingOperation ?? .sourceOver) {
|
|
precondition(NSGraphicsContext.current != nil,
|
|
"There must be a set current NSGraphicsContext")
|
|
__NSRectFillUsingOperation(self, operation)
|
|
}
|
|
|
|
/// Draws a frame around the inside of this rect in the current
|
|
/// NSGraphicsContext in the context's fill color
|
|
/// The compositing operation of the fill defaults to the context's
|
|
/// compositing operation, not necessarily using `.copy` like `NSFrameRect()`.
|
|
/// - precondition: There must be a set current NSGraphicsContext.
|
|
@available(swift 4)
|
|
public func frame(withWidth width: CGFloat = 1.0,
|
|
using operation: NSCompositingOperation =
|
|
NSGraphicsContext.current?.compositingOperation ?? .sourceOver) {
|
|
precondition(NSGraphicsContext.current != nil,
|
|
"There must be a set current NSGraphicsContext")
|
|
__NSFrameRectWithWidthUsingOperation(self, width, operation)
|
|
}
|
|
|
|
/// Modifies the current graphics context clipping path by intersecting it
|
|
/// with this rect.
|
|
/// This permanently modifies the graphics state, so the current state should
|
|
/// be saved beforehand and restored afterwards.
|
|
/// - precondition: There must be a set current NSGraphicsContext.
|
|
@available(swift 4)
|
|
public func clip() {
|
|
precondition(NSGraphicsContext.current != nil,
|
|
"There must be a set current NSGraphicsContext")
|
|
__NSRectClip(self)
|
|
}
|
|
}
|
|
|
|
extension Sequence where Iterator.Element == NSRect {
|
|
/// Fills this list of rects in the current NSGraphicsContext in the context's
|
|
/// fill color.
|
|
/// The compositing operation of the fill defaults to the context's
|
|
/// compositing operation, not necessarily using `.copy` like `NSRectFill()`.
|
|
/// - precondition: There must be a set current NSGraphicsContext.
|
|
@available(swift 4)
|
|
public func fill(using operation: NSCompositingOperation =
|
|
NSGraphicsContext.current?.compositingOperation ?? .sourceOver) {
|
|
precondition(NSGraphicsContext.current != nil,
|
|
"There must be a set current NSGraphicsContext")
|
|
let rects = Array(self)
|
|
let count = rects.count
|
|
guard count > 0 else { return }
|
|
rects.withUnsafeBufferPointer { rectBufferPointer in
|
|
guard let rectArray = rectBufferPointer.baseAddress else { return }
|
|
__NSRectFillListUsingOperation(rectArray, count, operation)
|
|
}
|
|
}
|
|
|
|
/// Modifies the current graphics context clipping path by intersecting it
|
|
/// with the graphical union of this list of rects
|
|
/// This permanently modifies the graphics state, so the current state should
|
|
/// be saved beforehand and restored afterwards.
|
|
/// - precondition: There must be a set current NSGraphicsContext.
|
|
@available(swift 4)
|
|
public func clip() {
|
|
precondition(NSGraphicsContext.current != nil,
|
|
"There must be a set current NSGraphicsContext")
|
|
let rects = Array(self)
|
|
let count = rects.count
|
|
guard count > 0 else { return }
|
|
rects.withUnsafeBufferPointer { rectBufferPointer in
|
|
guard let rectArray = rectBufferPointer.baseAddress else { return }
|
|
__NSRectClipList(rectArray, count)
|
|
}
|
|
}
|
|
}
|
|
|
|
extension Sequence where Iterator.Element == (CGRect, NSColor) {
|
|
/// Fills this list of rects in the current NSGraphicsContext with that rect's
|
|
/// associated color
|
|
/// The compositing operation of the fill defaults to the context's
|
|
/// compositing operation, not necessarily using `.copy` like `NSRectFill()`.
|
|
/// - precondition: There must be a set current NSGraphicsContext.
|
|
@available(swift 4)
|
|
public func fill(using operation: NSCompositingOperation =
|
|
NSGraphicsContext.current?.compositingOperation ?? .sourceOver) {
|
|
precondition(NSGraphicsContext.current != nil,
|
|
"There must be a set current NSGraphicsContext")
|
|
let rects = map { $0.0 }
|
|
let colors = map { $0.1 }
|
|
let count = rects.count
|
|
guard count > 0 else { return }
|
|
rects.withUnsafeBufferPointer { rectBufferPointer in
|
|
colors.withUnsafeBufferPointer { colorBufferPointer in
|
|
guard let rectArray = rectBufferPointer.baseAddress else { return }
|
|
guard let colorArray = colorBufferPointer.baseAddress else { return }
|
|
__NSRectFillListWithColorsUsingOperation(
|
|
rectArray, colorArray, count, operation)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
extension Sequence where Iterator.Element == (CGRect, gray: CGFloat) {
|
|
/// Fills this list of rects in the current NSGraphicsContext with that rect's
|
|
/// associated gray component value in the DeviceGray color space.
|
|
/// The compositing operation of the fill defaults to the context's
|
|
/// compositing operation, not necessarily using `.copy` like
|
|
/// `NSRectFillListWithGrays()`.
|
|
/// - precondition: There must be a set current NSGraphicsContext.
|
|
@available(swift 4)
|
|
public func fill(using operation: NSCompositingOperation =
|
|
NSGraphicsContext.current?.compositingOperation ?? .sourceOver) {
|
|
// NSRectFillListWithGrays does not have a variant taking an operation, but
|
|
// is added here for consistency with the other drawing operations.
|
|
guard let graphicsContext = NSGraphicsContext.current else {
|
|
fatalError("There must be a set current NSGraphicsContext")
|
|
}
|
|
let cgContext: CGContext
|
|
if #available(macOS 10.10, *) {
|
|
cgContext = graphicsContext.cgContext
|
|
} else {
|
|
cgContext = Unmanaged<CGContext>.fromOpaque(
|
|
graphicsContext.graphicsPort).takeUnretainedValue()
|
|
}
|
|
cgContext.saveGState()
|
|
forEach {
|
|
cgContext.setFillColor(gray: $0.gray, alpha: 1.0)
|
|
__NSRectFillUsingOperation($0.0, operation)
|
|
}
|
|
cgContext.restoreGState()
|
|
}
|
|
}
|
|
|
|
extension NSWindow.Depth {
|
|
@available(swift 4)
|
|
public static func bestDepth(
|
|
colorSpaceName: NSColorSpaceName,
|
|
bitsPerSample: Int,
|
|
bitsPerPixel: Int,
|
|
isPlanar: Bool
|
|
) -> (NSWindow.Depth, isExactMatch: Bool) {
|
|
var isExactMatch: ObjCBool = false
|
|
let depth = __NSBestDepth(
|
|
colorSpaceName,
|
|
bitsPerSample, bitsPerPixel, isPlanar, &isExactMatch)
|
|
return (depth, isExactMatch: isExactMatch.boolValue)
|
|
}
|
|
@available(swift 4)
|
|
public static var availableDepths: [NSWindow.Depth] {
|
|
// __NSAvailableWindowDepths is NULL terminated, the length is not known up front
|
|
let depthsCArray = __NSAvailableWindowDepths()
|
|
var depths: [NSWindow.Depth] = []
|
|
var length = 0
|
|
var depth = depthsCArray[length]
|
|
while depth.rawValue != 0 {
|
|
depths.append(depth)
|
|
length += 1
|
|
depth = depthsCArray[length]
|
|
}
|
|
return depths
|
|
}
|
|
}
|
|
|
|
extension NSAnimationEffect {
|
|
private class _CompletionHandlerDelegate : NSObject {
|
|
var completionHandler: () -> Void = { }
|
|
@objc func animationEffectDidEnd(_ contextInfo: UnsafeMutableRawPointer?) {
|
|
completionHandler()
|
|
}
|
|
}
|
|
@available(swift 4)
|
|
public func show(centeredAt centerLocation: NSPoint, size: NSSize,
|
|
completionHandler: @escaping () -> Void = { }) {
|
|
let delegate = _CompletionHandlerDelegate()
|
|
delegate.completionHandler = completionHandler
|
|
// Note that the delegate of `__NSShowAnimationEffect` is retained for the
|
|
// duration of the animation.
|
|
__NSShowAnimationEffect(
|
|
self,
|
|
centerLocation,
|
|
size,
|
|
delegate,
|
|
#selector(_CompletionHandlerDelegate.animationEffectDidEnd(_:)),
|
|
nil)
|
|
}
|
|
}
|
|
|
|
extension NSSound {
|
|
@available(swift 4)
|
|
public static func beep() {
|
|
__NSBeep()
|
|
}
|
|
}
|