| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- /// A shape that has style information attached to it, including color and
- /// stroke style.
- public protocol StyledShape: Shape {
- /// The shape's stroke color.
- var strokeColor: Color? { get }
- /// The shape's fill color.
- var fillColor: Color? { get }
- /// The shape's stroke style.
- var strokeStyle: StrokeStyle? { get }
- }
- struct StyledShapeImpl<Base: Shape>: Sendable {
- var base: Base
- var strokeColor: Color?
- var fillColor: Color?
- var strokeStyle: StrokeStyle?
- init(
- base: Base,
- strokeColor: Color? = nil,
- fillColor: Color? = nil,
- strokeStyle: StrokeStyle? = nil
- ) {
- self.base = base
- if let styledBase = base as? any StyledShape {
- self.strokeColor = strokeColor ?? styledBase.strokeColor
- self.fillColor = fillColor ?? styledBase.fillColor
- self.strokeStyle = strokeStyle ?? styledBase.strokeStyle
- } else {
- self.strokeColor = strokeColor
- self.fillColor = fillColor
- self.strokeStyle = strokeStyle
- }
- }
- }
- extension StyledShapeImpl: StyledShape {
- func path(in bounds: Path.Rect) -> Path {
- return base.path(in: bounds)
- }
- func size(fitting proposal: ProposedViewSize) -> ViewSize {
- return base.size(fitting: proposal)
- }
- }
- extension Shape {
- public func fill(_ color: Color) -> some StyledShape {
- StyledShapeImpl(base: self, fillColor: color)
- }
- public func stroke(_ color: Color, style: StrokeStyle? = nil) -> some StyledShape {
- StyledShapeImpl(base: self, strokeColor: color, strokeStyle: style)
- }
- }
- extension StyledShape {
- @MainActor
- public func computeLayout<Backend: BaseAppBackend>(
- _ widget: Backend.Widget,
- children: any ViewGraphNodeChildren,
- proposedSize: ProposedViewSize,
- environment: EnvironmentValues,
- backend: Backend
- ) -> ViewLayoutResult {
- let size = size(fitting: proposedSize)
- return ViewLayoutResult.leafView(size: size)
- }
- @MainActor
- func commit<Backend: BaseAppBackend>(
- _ widget: Backend.Widget,
- children: any ViewGraphNodeChildren,
- layout: ViewLayoutResult,
- environment: EnvironmentValues,
- backend: Backend
- ) {
- func castBackend_inner<NewBackend: BaseAppBackend & BackendFeatures.Paths>(_ backend: NewBackend) {
- let widget = widget as! NewBackend.Widget
- let bounds = Path.Rect(
- x: 0.0,
- y: 0.0,
- width: layout.size.width,
- height: layout.size.height
- )
- let path = path(in: bounds)
- let storage = children as! ShapeStorage
- let pointsChanged = storage.oldPath?.actions != path.actions
- storage.oldPath = path
- let backendPath = storage.backendPath as! NewBackend.Path
- backend.updatePath(
- backendPath,
- path,
- bounds: bounds,
- pointsChanged: pointsChanged,
- environment: environment
- )
- backend.setSize(of: widget, to: layout.size.vector)
- backend.renderPath(
- backendPath,
- container: widget,
- strokeColor: (strokeColor ?? .clear).resolve(in: environment),
- fillColor: (fillColor ?? .clear).resolve(in: environment),
- overrideStrokeStyle: strokeStyle
- )
- }
- guard let castedBackend = backend as? any (BaseAppBackend & BackendFeatures.Paths) else {
- fatalError("Backend does not implement BackendFeatures.Paths")
- }
- castBackend_inner(castedBackend)
- }
- }
|