swiftui-native 0.0.1

SwiftUI from pure Rust — no Swift bridge, no shim, only swift-runtime calls
Documentation
//! Visual effects.

use super::*;
use crate::abi;
use crate::resolve;
use crate::mangle;
mangle::modifier_types! {
    /// `ModifiedContent<AnyView, _ShadowEffect>`
    pub(crate) SHADOW_T = ty("_ShadowEffect");
    /// `ModifiedContent<AnyView, _BlurEffect>`
    pub(crate) BLUR_T = ty("_BlurEffect");
    /// `ModifiedContent<AnyView, _RotationEffect>`
    pub(crate) ROTATION_T = ty("_RotationEffect");
    /// `ModifiedContent<AnyView, _ScaleEffect>`
    pub(crate) SCALE_T = ty("_ScaleEffect");
    /// `ModifiedContent<AnyView, _OffsetEffect>`
    pub(crate) OFFSET_T = ty("_OffsetEffect");
    /// `ModifiedContent<AnyView, _BrightnessEffect>`
    pub(crate) BRIGHTNESS_T = ty("_BrightnessEffect");
    /// `ModifiedContent<AnyView, _SaturationEffect>`
    pub(crate) SATURATION_T = ty("_SaturationEffect");
    /// `ModifiedContent<AnyView, _ContrastEffect>`
    pub(crate) CONTRAST_T = ty("_ContrastEffect");
    /// `ModifiedContent<AnyView, _GrayscaleEffect>`
    pub(crate) GRAYSCALE_T = ty("_GrayscaleEffect");
}









/// Apply `.shadow(color:radius:x:y:)`.
pub fn shadow(view: &ViewHandle, c: crate::Color, radius: f64, dx: f64, dy: f64) -> ViewHandle {
    unsafe {
        let (_, _, size) = SHADOW_T.applied_to(view.meta);
        // Color is a single class reference, so it goes in an integer register.
        let col = color_value(c.r, c.g, c.b, c.a);
        let r = abi::call_modifier(resolve::shadow_fn(), view.value_ptr(), view.meta, view.wt,
            &[col],
            [radius, dx, dy, 0.0],
            size,
        );
        wrap_modified(r, &SHADOW_T, view)
    }
}

/// Apply `.blur(radius:)`.
pub fn blur(view: &ViewHandle, radius: f64) -> ViewHandle {
    unsafe {
        let (_, _, size) = BLUR_T.applied_to(view.meta);
        let r = abi::call_modifier(resolve::blur_fn(), view.value_ptr(), view.meta, view.wt, &[0], [radius, 0.0, 0.0, 0.0], size);
        wrap_modified(r, &BLUR_T, view)
    }
}

/// Apply `.rotationEffect(.degrees(_), anchor:)`.
pub fn rotation(view: &ViewHandle, degrees: f64, anchor_x: f64, anchor_y: f64) -> ViewHandle {
    unsafe {
        let (_, _, size) = ROTATION_T.applied_to(view.meta);
        // Angle stores radians; UnitPoint is two CGFloats.
        let radians = degrees * std::f64::consts::PI / 180.0;
        let r = abi::call_modifier(resolve::rotation_fn(), view.value_ptr(), view.meta, view.wt,
            &[],
            [radians, anchor_x, anchor_y, 0.0],
            size,
        );
        wrap_modified(r, &ROTATION_T, view)
    }
}

/// Apply `.scaleEffect(_:anchor:)`.
pub fn scale(view: &ViewHandle, sx: f64, sy: f64, anchor_x: f64, anchor_y: f64) -> ViewHandle {
    unsafe {
        let (_, _, size) = SCALE_T.applied_to(view.meta);
        let r = abi::call_modifier(resolve::scale_fn(), view.value_ptr(), view.meta, view.wt, &[], [sx, sy, anchor_x, anchor_y], size);
        wrap_modified(r, &SCALE_T, view)
    }
}

/// Apply `.offset(x:y:)`.
pub fn offset(view: &ViewHandle, dx: f64, dy: f64) -> ViewHandle {
    unsafe {
        let (_, _, size) = OFFSET_T.applied_to(view.meta);
        let r = abi::call_modifier(resolve::offset_fn(), view.value_ptr(), view.meta, view.wt, &[], [dx, dy, 0.0, 0.0], size);
        wrap_modified(r, &OFFSET_T, view)
    }
}

macro_rules! scalar_effect {
    ($name:ident, $sym:ident, $ty:ident, $doc:literal) => {
        #[doc = $doc]
        pub fn $name(view: &ViewHandle, amount: f64) -> ViewHandle {
            unsafe {
                let (_, _, size) = $ty.applied_to(view.meta);
                let r =
                    abi::call_modifier(resolve::$sym(), view.value_ptr(), view.meta, view.wt, &[], [amount, 0.0, 0.0, 0.0], size);
                wrap_modified(r, &$ty, view)
            }
        }
    };
}

scalar_effect!(brightness, brightness_fn, BRIGHTNESS_T, "Apply `.brightness(_:)`.");
scalar_effect!(saturation, saturation_fn, SATURATION_T, "Apply `.saturation(_:)`.");
scalar_effect!(contrast, contrast_fn, CONTRAST_T, "Apply `.contrast(_:)`.");
scalar_effect!(grayscale, grayscale_fn, GRAYSCALE_T, "Apply `.grayscale(_:)`.");