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
use ribir_painter::Radius;
use wrap_render::WrapRender;
use super::*;
/// A widget that provides corner radius information to its host, affecting
/// background and border rendering.
///
/// This is a built-in `FatObj` field. Setting the `radius` field attaches a
/// `RadiusWidget` that provides corner radii to downstream painters.
///
/// # Example
///
/// Display a red container with a radius of 10.
///
/// ```rust
/// use ribir::prelude::*;
///
/// container! {
/// background: Color::RED,
/// radius: Radius::all(10.),
/// size: Size::new(100., 100.),
/// };
/// ```
///
/// If you set the radius in different `FatObj`, ensure it is set in the
/// outermost `FatObj`. Otherwise, the outer border or background will ignore
/// it.
///
/// For example:
///
/// ```rust
/// use ribir::prelude::*;
///
/// let _ = fn_widget! {
/// @Background {
/// background: Color::RED,
/// radius: Radius::all(10.),
/// @BorderWidget {
/// border: Border::all(BorderSide::new(1., Color::BLACK.into())),
/// @Container {
/// size: Size::new(100., 100.)
/// }
/// }
/// }
/// };
/// ```
///
/// This widget will create a border with a radius of 10 and a red box with a
/// radius.
#[derive(Default, Clone)]
pub struct RadiusWidget {
/// A border to draw above the background
pub radius: Radius,
}
impl Declare for RadiusWidget {
type Builder = FatObj<()>;
#[inline]
fn declarer() -> Self::Builder { FatObj::new(()) }
}
impl WrapRender for RadiusWidget {
fn paint(&self, host: &dyn Render, ctx: &mut PaintingCtx) {
let mut provider = Provider::new(self.radius);
provider.setup(ctx.as_mut());
host.paint(ctx);
provider.restore(ctx.as_mut());
}
#[inline]
fn wrapper_dirty_phase(&self) -> DirtyPhase { DirtyPhase::Paint }
#[cfg(feature = "debug")]
fn debug_type(&self) -> Option<&'static str> { Some("radius") }
#[cfg(feature = "debug")]
fn debug_properties(&self) -> Option<serde_json::Value> {
let r = self.radius;
Some(serde_json::json!({
"corners": {
"topLeft": r.top_left,
"topRight": r.top_right,
"bottomLeft": r.bottom_left,
"bottomRight": r.bottom_right
}
}))
}
}
impl_compose_child_for_wrap_render!(RadiusWidget);