NSAttributedTextView // Compatibility tweaks.

This commit is contained in:
ShikiSuen 2023-09-19 17:26:56 +08:00
parent 90c35db4d1
commit db4ccbb705
3 changed files with 89 additions and 3 deletions

View File

@ -22,5 +22,9 @@ let package = Package(
.product(name: "CocoaExtension", package: "vChewing_CocoaExtension"),
]
),
.testTarget(
name: "NSAttributedTextViewTests",
dependencies: ["NSAttributedTextView"]
),
]
)

View File

@ -72,6 +72,18 @@ public class NSAttributedTextView: NSView {
}
}
public init() {
super.init(frame: .zero)
#if compiler(>=5.9) && canImport(AppKit, _version: "14.0")
clipsToBounds = true // View
#endif
}
@available(*, unavailable)
required init?(coder _: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
public func attributedStringValue(areaCalculation: Bool = false) -> NSAttributedString {
var newAttributes = attributes
let isVertical: Bool = !(direction == .horizontal)
@ -131,8 +143,7 @@ public class NSAttributedTextView: NSView {
}
override public func draw(_ rect: CGRect) {
let context = NSGraphicsContext.current?.cgContext
guard let context = context else { return }
guard let currentNSGraphicsContext = NSGraphicsContext.current else { return }
let setter = CTFramesetterCreateWithAttributedString(attributedStringValue())
let path = CGPath(rect: rect, transform: nil)
let theCTFrameProgression: CTFrameProgression = {
@ -152,7 +163,16 @@ public class NSAttributedTextView: NSView {
let bgPath: NSBezierPath = .init(roundedRect: rect, xRadius: 0, yRadius: 0)
bgPath.fill()
currentRect = rect
CTFrameDraw(newFrame, context)
if #unavailable(macOS 10.10) {
// NSGraphicsContext.current?.cgContext macOS 10.10 Yosemite
//
let contextPtr: Unmanaged<CGContext>? = Unmanaged.fromOpaque(currentNSGraphicsContext.graphicsPort)
let theContext: CGContext? = contextPtr?.takeUnretainedValue()
guard let theContext = theContext else { return }
CTFrameDraw(newFrame, theContext)
} else {
CTFrameDraw(newFrame, currentNSGraphicsContext.cgContext)
}
}
}

View File

@ -0,0 +1,62 @@
// (c) 2021 and onwards The vChewing Project (MIT-NTL License).
// ====================
// This code is released under the MIT license (SPDX-License-Identifier: MIT)
// ... with NTL restriction stating that:
// No trademark license is granted to use the trade names, trademarks, service
// marks, or product names of Contributor, except as required to fulfill notice
// requirements defined in MIT License.
import AppKit
import CocoaExtension
import Foundation
@testable import NSAttributedTextView
import Shared
import XCTest
class MainAssemblyTests: XCTestCase {
func testView() throws {
let testCtl: testController = .init()
var rect = testCtl.attrView.shrinkFrame()
var bigRect = rect
bigRect.size.width += NSFont.systemFontSize
bigRect.size.height += NSFont.systemFontSize
rect.origin.x += ceil(NSFont.systemFontSize / 2)
rect.origin.y += ceil(NSFont.systemFontSize / 2)
testCtl.attrView.frame = rect
testCtl.window?.setFrame(bigRect, display: true)
testCtl.window?.orderFront(nil)
testCtl.attrView.draw(testCtl.attrView.frame)
testCtl.window?.setIsVisible(true)
}
}
class testController: NSWindowController {
var attrView: NSAttributedTextView
init() {
let contentRect = NSRect(x: 128.0, y: 128.0, width: 300.0, height: 20.0)
let styleMask: NSWindow.StyleMask = [.borderless, .nonactivatingPanel]
let panel = NSPanel(
contentRect: contentRect, styleMask: styleMask, backing: .buffered, defer: false
)
panel.level = NSWindow.Level(Int(max(CGShieldingWindowLevel(), kCGPopUpMenuWindowLevel)) + 2)
panel.hasShadow = true
panel.backgroundColor = NSColor.clear
panel.isOpaque = false
panel.isMovable = false
panel.contentView?.wantsLayer = true
panel.contentView?.layer?.cornerRadius = 7
panel.contentView?.layer?.backgroundColor = NSColor.controlBackgroundColor.cgColor
attrView = NSAttributedTextView()
attrView.backgroundColor = NSColor.clear
attrView.textColor = NSColor.textColor
attrView.needsDisplay = true
attrView.text = "114514"
panel.contentView?.addSubview(attrView)
super.init(window: panel)
}
@available(*, unavailable)
required init?(coder _: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}