Files
phranck db8ea40c0a Refactor: Fix SwiftLint warnings and refactor StatusBar to _StatusBarCore pattern
- 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)
2026-02-15 02:35:18 +01:00

100 lines
3.3 KiB
Swift
Raw Permalink 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
// 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)
}
}