1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
use crate::{
    component::containers::{paper::PaperProps, wrap_paper::wrap_paper},
    theme::{ThemeColor, ThemedWidgetProps},
};
use raui_core::prelude::*;
use serde::{Deserialize, Serialize};

#[derive(PropsData, Debug, Clone, Serialize, Deserialize)]
#[props_data(raui_core::props::PropsData)]
#[prefab(raui_core::Prefab)]
pub struct ContextPaperProps {
    #[serde(default = "ContextPaperProps::default_margin")]
    pub margin: Rect,
    #[serde(default = "ContextPaperProps::default_frame")]
    pub frame: Option<Scalar>,
    #[serde(default)]
    pub notify_backdrop_accept: WidgetIdOrRef,
}

impl Default for ContextPaperProps {
    fn default() -> Self {
        Self {
            margin: Self::default_margin(),
            frame: Self::default_frame(),
            notify_backdrop_accept: Default::default(),
        }
    }
}

impl ContextPaperProps {
    fn default_margin() -> Rect {
        Rect {
            left: 10.0,
            right: 10.0,
            top: 10.0,
            bottom: 10.0,
        }
    }

    #[allow(clippy::unnecessary_wraps)]
    fn default_frame() -> Option<Scalar> {
        Some(2.0)
    }
}

pub fn context_paper(context: WidgetContext) -> WidgetNode {
    let WidgetContext {
        idref,
        key,
        props,
        named_slots,
        ..
    } = context;
    unpack_named_slots!(named_slots => {content, context});

    let ContextPaperProps {
        margin,
        frame,
        notify_backdrop_accept,
    } = props.read_cloned_or_default();

    let context_size_props = SizeBoxProps {
        width: SizeBoxSizeValue::Content,
        height: SizeBoxSizeValue::Content,
        ..Default::default()
    };
    let themed_props = props.read_cloned_or_else(|| ThemedWidgetProps {
        color: ThemeColor::Primary,
        ..Default::default()
    });
    let paper_props = props.read_cloned_or_else(|| PaperProps {
        frame: frame.map(|v| ImageBoxFrame::from((v, true))),
        ..Default::default()
    });
    let wrap_props = props
        .clone()
        .with(themed_props)
        .with(paper_props)
        .with(WrapBoxProps {
            margin,
            ..Default::default()
        });
    let backdrop_size_props = SizeBoxProps {
        width: SizeBoxSizeValue::Fill,
        height: SizeBoxSizeValue::Fill,
        ..Default::default()
    };

    widget! {
        (#{key} | {idref.cloned()} portals_context_box: {props.clone()} {
            content = {content}
            context = (#{"size"} size_box: {context_size_props} {
                content = (#{"wrap"} wrap_paper: {wrap_props} {
                    content = {context}
                })
            })
            backdrop = (#{"button"} button: {ButtonNotifyProps(notify_backdrop_accept)} {
                content = (#{"size"} size_box: {backdrop_size_props})
            })
        })
    }
}