Add display model

This commit is contained in:
Guille Gonzalez
2026-01-03 07:45:34 +01:00
parent e9657c186e
commit 8e4db3cf0e
11 changed files with 365 additions and 0 deletions

View File

@@ -0,0 +1,79 @@
import CoreGraphics
import Foundation
extension Math {
final class DisplayLargeOperator: DisplayNode {
var upperLimit: DisplayList?
var lowerLimit: DisplayList?
var nucleus: DisplayNode?
var limitShift: CGFloat = 0
var upperLimitGap: CGFloat = 0 { didSet { updateUpperLimitPosition() } }
var lowerLimitGap: CGFloat = 0 { didSet { updateLowerLimitPosition() } }
var extraPadding: CGFloat = 0
init(nucleus: DisplayNode?, upperLimit: DisplayList?, lowerLimit: DisplayList?, limitShift: CGFloat, extraPadding: CGFloat) {
self.upperLimit = upperLimit
self.lowerLimit = lowerLimit
self.nucleus = nucleus
self.limitShift = limitShift
self.extraPadding = extraPadding
super.init()
var maxWidth = max(nucleus?.width ?? 0, upperLimit?.width ?? 0)
maxWidth = max(maxWidth, lowerLimit?.width ?? 0)
width = maxWidth
}
override var ascent: CGFloat {
get {
guard let nucleus else { return 0 }
if let upperLimit {
return nucleus.ascent + extraPadding + upperLimit.ascent + upperLimitGap + upperLimit.descent
}
return nucleus.ascent
}
set { super.ascent = newValue }
}
override var descent: CGFloat {
get {
guard let nucleus else { return 0 }
if let lowerLimit {
return nucleus.descent + extraPadding + lowerLimitGap + lowerLimit.descent + lowerLimit.ascent
}
return nucleus.descent
}
set { super.descent = newValue }
}
override var position: CGPoint {
didSet {
updateLowerLimitPosition()
updateUpperLimitPosition()
updateNucleusPosition()
}
}
private func updateLowerLimitPosition() {
guard let lowerLimit, let nucleus else { return }
lowerLimit.position = CGPoint(
x: position.x - limitShift + (width - lowerLimit.width) / 2,
y: position.y - nucleus.descent - lowerLimitGap - lowerLimit.ascent
)
}
private func updateUpperLimitPosition() {
guard let upperLimit, let nucleus else { return }
upperLimit.position = CGPoint(
x: position.x + limitShift + (width - upperLimit.width) / 2,
y: position.y + nucleus.ascent + upperLimitGap + upperLimit.descent
)
}
private func updateNucleusPosition() {
guard let nucleus else { return }
nucleus.position = CGPoint(x: position.x + (width - nucleus.width) / 2, y: position.y)
}
}
}