Files
TUIkit/Sources/TUIkit/Modifiers/OverlayModifier.swift
T
phranck e214215610 Refactor: Replace MainActor.assumeIsolated with @preconcurrency Equatable
- Migrate 20 Equatable conformances across 17 files from
  nonisolated + MainActor.assumeIsolated to @preconcurrency Equatable (SE-0423)
- Remove unnecessary import Foundation from 29 source files
- Extract TextFieldHandler clipboard ops into TextFieldHandler+Clipboard.swift
- Extract RenderContext into RenderContext.swift (Renderable.swift 553 -> 279 lines)
- Extract ANSIColor enum into ANSIColor.swift (Color.swift 600 -> 533 lines)
- Add deprecation timeline note for progressBarStyle(_:)
- Migrate test usages from progressBarStyle to trackStyle
2026-02-14 02:10:26 +01:00

85 lines
2.7 KiB
Swift
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 🖥 TUIKit Terminal UI Kit for Swift
// OverlayModifier.swift
//
// Created by LAYERED.work
// License: MIT
/// Internal modifier that layers an overlay view on top of the base content.
///
/// The overlay is rendered on top of the base content. Both views are rendered
/// to their natural size, and the overlay is positioned according to the
/// specified alignment within the base content's bounds.
public struct OverlayModifier<Base: View, Overlay: View>: View {
/// The base content.
let base: Base
/// The overlay content.
let overlay: Overlay
/// The alignment of the overlay within the base bounds.
let alignment: Alignment
public var body: Never {
fatalError("OverlayModifier renders via Renderable")
}
}
// MARK: - Equatable Conformance
extension OverlayModifier: @preconcurrency Equatable where Base: Equatable, Overlay: Equatable {
public static func == (lhs: OverlayModifier<Base, Overlay>, rhs: OverlayModifier<Base, Overlay>) -> Bool {
lhs.base == rhs.base &&
lhs.overlay == rhs.overlay &&
lhs.alignment == rhs.alignment
}
}
// MARK: - Renderable
extension OverlayModifier: Renderable {
func renderToBuffer(context: RenderContext) -> FrameBuffer {
// Render both contents
let baseBuffer = TUIkit.renderToBuffer(base, context: context)
let overlayBuffer = TUIkit.renderToBuffer(overlay, context: context)
guard !baseBuffer.isEmpty else {
return overlayBuffer
}
guard !overlayBuffer.isEmpty else {
return baseBuffer
}
// Calculate the position of the overlay based on alignment
let baseWidth = baseBuffer.width
let baseHeight = baseBuffer.height
let overlayWidth = overlayBuffer.width
let overlayHeight = overlayBuffer.height
// Calculate horizontal position
let horizontalOffset: Int
switch alignment.horizontal {
case .leading:
horizontalOffset = 0
case .center:
horizontalOffset = max(0, (baseWidth - overlayWidth) / 2)
case .trailing:
horizontalOffset = max(0, baseWidth - overlayWidth)
}
// Calculate vertical position
let verticalOffset: Int
switch alignment.vertical {
case .top:
verticalOffset = 0
case .center:
verticalOffset = max(0, (baseHeight - overlayHeight) / 2)
case .bottom:
verticalOffset = max(0, baseHeight - overlayHeight)
}
// Composite the overlay onto the base
return baseBuffer.composited(with: overlayBuffer, at: (x: horizontalOffset, y: verticalOffset))
}
}