cotis-defaults 0.1.0-alpha

Modular Rust UI framework core
Documentation
//! Element configuration data passed into Cotis layout.
//!
//! This module defines the configuration payload attached to each element before
//! layout runs, including style, optional image data, and optional custom payloads.
use crate::colors::Color;
#[cfg(feature = "complex_color")]
use crate::colors::ColorLayer;
use crate::element_configs::image_config::ImageConfig;
use crate::element_configs::style::types::{
    Alignment, ClipElementConfig, FloatingAttachPointType, LayoutAlignmentX, LayoutAlignmentY,
    LayoutDirection, Padding, PointerCaptureMode,
};
use crate::element_configs::style::{
    BorderElementStyle, BorderWidthStyle, CornerRadiiStyle, CotisStyle, FloatingElementStyle,
    LayoutStyle,
};
use cotis::utils::ElementIdConfig;
use cotis::utils::OwnedOrRef;

/// Image-specific element payload wrappers.
pub mod image_config;
/// Convenient type aliases for common element config signatures.
pub mod premade_configs;
/// Styling structures and layout-related style primitives.
pub mod style;
/// Text and rich-text element configuration types.
pub mod text_config;

/// Generic element configuration consumed by layout crates.
///
/// Type parameters:
/// - `'render`: lifetime of borrowed config data.
/// - `Sizing`: sizing model (`Sizing` or `DoubleAxisSizing` in most integrations).
/// - `ImageElementData`: payload type used when [`image`](Self::image) is present.
/// - `CustomElementData`: custom renderer-specific payload.
/// - `ExtraData`: metadata propagated to render command info.
#[derive(Debug, Clone)]
#[cfg_attr(
    feature = "serialization",
    derive(serde::Serialize, serde::Deserialize)
)]
#[cfg_attr(
    feature = "serialization",
    serde(bound(deserialize = "
    Sizing: serde::de::DeserializeOwned,
    ImageElementData: serde::de::DeserializeOwned,
    CustomElementData: serde::de::DeserializeOwned,
    ExtraData: serde::de::DeserializeOwned
"))
)]
pub struct ElementConfig<
    'render,
    Sizing: 'render,
    ImageElementData: 'render,
    CustomElementData: 'render,
    ExtraData: 'render,
> {
    /// ID and identity behavior configuration for the element.
    pub id_config: ElementIdConfig<'render>,
    /// Style applied to this element.
    pub style: CotisStyle<Sizing>,
    /// Optional image payload.
    pub image: Option<ImageConfig<'render, ImageElementData>>,
    /// Optional custom payload consumed by renderer-specific logic.
    pub custom: Option<OwnedOrRef<'render, CustomElementData>>,
    /// Optional extra metadata forwarded to command-level info structs.
    pub extra_data: Option<OwnedOrRef<'render, ExtraData>>,
}

impl<
    'render,
    Sizing: 'render,
    ImageElementData: 'render,
    CustomElementData: 'render,
    ExtraData: 'render,
> Default for ElementConfig<'render, Sizing, ImageElementData, CustomElementData, ExtraData>
where
    Sizing: Default,
{
    fn default() -> Self {
        Self {
            id_config: ElementIdConfig::new_empty(),
            style: Default::default(),
            image: None,
            custom: None,
            extra_data: None,
        }
    }
}

impl<Sizing: Default> Default for CotisStyle<Sizing> {
    /// Builds a style with transparent background, no borders, no floating, and
    /// default layout/sizing values.
    fn default() -> Self {
        Self {
            sizing: Sizing::default(),
            layout: Default::default(),
            #[cfg(not(feature = "complex_color"))]
            background_color: Color {
                r: 0.0,
                g: 0.0,
                b: 0.0,
                a: 0.0,
            },
            #[cfg(feature = "complex_color")]
            background_color: ColorLayer::Solid(Color {
                r: 0.0,
                g: 0.0,
                b: 0.0,
                a: 0.0,
            }),
            corner_radius: CornerRadiiStyle {
                top_left: 0.0,
                top_right: 0.0,
                bottom_left: 0.0,
                bottom_right: 0.0,
            },
            floating: Default::default(),
            clip: ClipElementConfig {
                horizontal: false,
                vertical: false,
                child_offset: Default::default(),
            },
            border: BorderElementStyle {
                color: Color {
                    r: 0.0,
                    g: 0.0,
                    b: 0.0,
                    a: 255.0,
                },
                width: BorderWidthStyle {
                    left: 0.0,
                    right: 0.0,
                    top: 0.0,
                    bottom: 0.0,
                    between_children: 0.0,
                },
            },
        }
    }
}

impl Default for LayoutStyle {
    /// Creates a left-to-right layout with zero padding and gap.
    fn default() -> Self {
        Self {
            padding: Padding {
                top: 0.0,
                bottom: 0.0,
                right: 0.0,
                left: 0.0,
            },
            child_gap: 0.0,
            child_alignment: Alignment {
                x: LayoutAlignmentX::Left,
                y: LayoutAlignmentY::Top,
            },
            layout_direction: LayoutDirection::LeftToRight,
            #[cfg(feature = "child_wrapping")]
            child_wrapping: false,
        }
    }
}

impl Default for FloatingElementStyle {
    /// Creates a non-offset floating style attached to the parent top-left.
    fn default() -> Self {
        Self {
            offset: Default::default(),
            expand: Default::default(),
            z_index: 0,
            attach_point: FloatingAttachPointType::LeftTop,
            pointer_capture_mode: PointerCaptureMode::Capture,
        }
    }
}