mirror of
https://github.com/phranck/TUIkit.git
synced 2026-05-21 09:50:35 +00:00
db8ea40c0a
- Fix 80 SwiftLint warnings (159 -> 79): vertical_whitespace, prefer_self_in_static_references, modifier_order, trailing_newline, trailing_whitespace, prefer_for_where, unneeded_synthesized_initializer, redundant_type_annotation, implicit_optional_initialization, superfluous_disable_command, shorthand_optional_binding, syntactic_sugar, empty_string, vertical_whitespace_closing_braces, identifier_name in BadgeModifier - Refactor StatusBar from direct Renderable to _StatusBarCore pattern (public View with real body wrapping private Renderable core)
100 lines
3.3 KiB
Swift
100 lines
3.3 KiB
Swift
// 🖥️ TUIKit — Terminal UI Kit for Swift
|
||
// ViewModifier.swift
|
||
//
|
||
// Created by LAYERED.work
|
||
// License: MIT
|
||
|
||
import TUIkitCore
|
||
/// A modifier that transforms a view's rendered output.
|
||
///
|
||
/// `ViewModifier` works on the `FrameBuffer` level: it takes a rendered
|
||
/// buffer and returns a transformed buffer. This allows modifiers like
|
||
/// `.padding()` and `.frame()` to manipulate layout after rendering.
|
||
///
|
||
/// # Example
|
||
///
|
||
/// ```swift
|
||
/// struct MyModifier: ViewModifier {
|
||
/// func modify(buffer: FrameBuffer, context: RenderContext) -> FrameBuffer {
|
||
/// // transform the buffer
|
||
/// return buffer
|
||
/// }
|
||
/// }
|
||
/// ```
|
||
@MainActor
|
||
public protocol ViewModifier {
|
||
/// Transforms a rendered buffer.
|
||
///
|
||
/// - Parameters:
|
||
/// - buffer: The rendered content of the wrapped view.
|
||
/// - context: The rendering context.
|
||
/// - Returns: The modified buffer.
|
||
func modify(buffer: FrameBuffer, context: RenderContext) -> FrameBuffer
|
||
|
||
/// Adjusts the rendering context before the wrapped content is rendered.
|
||
///
|
||
/// Override this method in modifiers that consume space (like padding)
|
||
/// to reduce `availableWidth` or `availableHeight` so that flexible
|
||
/// child views size themselves correctly.
|
||
///
|
||
/// The default implementation returns the context unchanged.
|
||
///
|
||
/// - Parameter context: The current rendering context.
|
||
/// - Returns: The adjusted context for content rendering.
|
||
func adjustContext(_ context: RenderContext) -> RenderContext
|
||
}
|
||
|
||
extension ViewModifier {
|
||
public func adjustContext(_ context: RenderContext) -> RenderContext {
|
||
context
|
||
}
|
||
}
|
||
|
||
// MARK: - ModifiedView
|
||
|
||
/// A view that wraps another view with a modifier.
|
||
///
|
||
/// This is the return type of modifier methods like `.frame()` and `.padding()`.
|
||
/// It is created automatically — users don't instantiate this directly.
|
||
///
|
||
/// `ModifiedView` is a **primitive view**: it declares `body: Never`
|
||
/// and conforms to `Renderable`. The rendering system calls
|
||
/// `renderToBuffer(context:)` which first renders the
|
||
/// wrapped `content`, then applies the modifier's transformation.
|
||
/// The `body` property is never called.
|
||
///
|
||
/// - Important: This is framework infrastructure. Created automatically by
|
||
/// `.modifier()`. Do not instantiate directly.
|
||
public struct ModifiedView<Content: View, Modifier: ViewModifier>: View {
|
||
/// The original view.
|
||
public let content: Content
|
||
|
||
/// The modifier to apply.
|
||
public let modifier: Modifier
|
||
|
||
/// Creates a modified view.
|
||
///
|
||
/// - Parameters:
|
||
/// - content: The original view.
|
||
/// - modifier: The modifier to apply.
|
||
public init(content: Content, modifier: Modifier) {
|
||
self.content = content
|
||
self.modifier = modifier
|
||
}
|
||
|
||
/// Never called — rendering is handled by `Renderable` conformance.
|
||
public var body: Never {
|
||
fatalError("ModifiedView renders via Renderable")
|
||
}
|
||
}
|
||
|
||
// MARK: - ModifiedView Rendering
|
||
|
||
extension ModifiedView: Renderable {
|
||
public func renderToBuffer(context: RenderContext) -> FrameBuffer {
|
||
let adjustedContext = modifier.adjustContext(context)
|
||
let childBuffer = TUIkitView.renderToBuffer(content, context: adjustedContext)
|
||
return modifier.modify(buffer: childBuffer, context: context)
|
||
}
|
||
}
|