Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ClipEffect interface #98

Merged
merged 1 commit into from
Jun 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 130 additions & 0 deletions Sources/OpenSwiftUI/View/Modifier/ClipEffect.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import Foundation

// MARK: - ClipEffect

@frozen
public struct _ClipEffect<ClipShape> where ClipShape: Shape {
public var shape: ClipShape
public var style: FillStyle

@inlinable
public init(shape: ClipShape, style: FillStyle = FillStyle()) {
self.shape = shape
self.style = style
}

public var animatableData: ClipShape.AnimatableData {
get { shape.animatableData }
set { shape.animatableData = newValue }
}

public typealias AnimatableData = ClipShape.AnimatableData
public typealias Body = Swift.Never
}

// FIXME
extension _ClipEffect: PrimitiveViewModifier {}

// MARK: - View Extension

extension View {

/// Sets a clipping shape for this view.
///
/// Use `clipShape(_:style:)` to clip the view to the provided shape. By
/// applying a clipping shape to a view, you preserve the parts of the view
/// covered by the shape, while eliminating other parts of the view. The
/// clipping shape itself isn't visible.
///
/// For example, this code applies a circular clipping shape to a `Text`
/// view:
///
/// Text("Clipped text in a circle")
/// .frame(width: 175, height: 100)
/// .foregroundColor(Color.white)
/// .background(Color.black)
/// .clipShape(Circle())
///
/// The resulting view shows only the portion of the text that lies within
/// the bounds of the circle.
///
/// ![A screenshot of text clipped to the shape of a
/// circle.](OpenSwiftUI-View-clipShape.png)
///
/// - Parameters:
/// - shape: The clipping shape to use for this view. The `shape` fills
/// the view's frame, while maintaining its aspect ratio.
/// - style: The fill style to use when rasterizing `shape`.
///
/// - Returns: A view that clips this view to `shape`, using `style` to
/// define the shape's rasterization.
@inlinable
public func clipShape<S>(_ shape: S, style: FillStyle = FillStyle()) -> some View where S: Shape {
modifier(_ClipEffect(shape: shape, style: style))
}


/// Clips this view to its bounding rectangular frame.
///
/// Use the `clipped(antialiased:)` modifier to hide any content that
/// extends beyond the layout bounds of the shape.
///
/// By default, a view's bounding frame is used only for layout, so any
/// content that extends beyond the edges of the frame is still visible.
///
/// Text("This long text string is clipped")
/// .fixedSize()
/// .frame(width: 175, height: 100)
/// .clipped()
/// .border(Color.gray)
///
/// ![Screenshot showing text clipped to its
/// frame.](OpenSwiftUI-View-clipped.png)
///
/// - Parameter antialiased: A Boolean value that indicates whether the
/// rendering system applies smoothing to the edges of the clipping
/// rectangle.
///
/// - Returns: A view that clips this view to its bounding frame.
@inlinable
public func clipped(antialiased: Bool = false) -> some View {
clipShape(
Rectangle(),
style: FillStyle(antialiased: antialiased)
)
}


/// Clips this view to its bounding frame, with the specified corner radius.
///
/// By default, a view's bounding frame only affects its layout, so any
/// content that extends beyond the edges of the frame remains visible. Use
/// `cornerRadius(_:antialiased:)` to hide any content that extends beyond
/// these edges while applying a corner radius.
///
/// The following code applies a corner radius of 25 to a text view:
///
/// Text("Rounded Corners")
/// .frame(width: 175, height: 75)
/// .foregroundColor(Color.white)
/// .background(Color.black)
/// .cornerRadius(25)
///
/// ![A screenshot of a rectangle with rounded corners bounding a text
/// view.](OpenSwiftUI-View-cornerRadius.png)
///
/// - Parameter antialiased: A Boolean value that indicates whether the
/// rendering system applies smoothing to the edges of the clipping
/// rectangle.
///
/// - Returns: A view that clips this view to its bounding frame with the
/// specified corner radius.
@available(*, deprecated, message: "Use `clipShape` or `fill` instead.")
@inlinable
public func cornerRadius(_ radius: CGFloat, antialiased: Bool = true) -> some View {
clipShape(
RoundedRectangle(cornerRadius: radius),
style: FillStyle(antialiased: antialiased)
)
}
}
18 changes: 18 additions & 0 deletions Sources/OpenSwiftUI/View/Shape/RoundedCornerStyle.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// ShapeRole.swift
// OpenSwiftUI
//
// Audited for RELEASE_2021
// Status: Complete

/// Defines the shape of a rounded rectangle's corners.
public enum RoundedCornerStyle: Sendable {
/// Quarter-circle rounded rect corners.
case circular

/// Continuous curvature rounded rect corners.
case continuous
}

extension RoundedCornerStyle: Equatable {}
extension RoundedCornerStyle: Hashable {}
30 changes: 30 additions & 0 deletions Sources/OpenSwiftUI/View/Shape/RoundedRectangle.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import Foundation

@frozen
public struct RoundedRectangle: Shape {
public var cornerSize: CGSize
public var style: RoundedCornerStyle

@inlinable
public init(cornerSize: CGSize, style: RoundedCornerStyle = .circular) {
self.cornerSize = cornerSize
self.style = style
}

@inlinable
public init(cornerRadius: CGFloat, style: RoundedCornerStyle = .circular) {
let cornerSize = CGSize(width: cornerRadius, height: cornerRadius)
self.init(cornerSize: cornerSize, style: style)
}

public func path(in rect: CGRect) -> Path {
fatalError("TODO")
}
public var animatableData: CGSize.AnimatableData {
get { cornerSize.animatableData }
set { cornerSize.animatableData = newValue }
}

public typealias Body = _ShapeView<RoundedRectangle, ForegroundStyle>
}

1 change: 1 addition & 0 deletions Sources/OpenSwiftUI/View/Shape/StrokeStyle.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// Audited for RELEASE_2021
// Status: Complete

import Foundation
#if canImport(CoreGraphics)
import CoreGraphics
#else
Expand Down
Loading