vizia_core/views/
badge.rs
1use crate::prelude::*;
2
3#[derive(Default, Debug, Clone, Copy, Data, PartialEq)]
5pub enum BadgePlacement {
6 TopLeft,
8 Top,
10 #[default]
12 TopRight,
13 Left,
15 Right,
17 BottomLeft,
19 Bottom,
21 BottomRight,
23}
24
25impl_res_simple!(BadgePlacement);
26
27#[derive(Lens)]
29pub struct Badge {
30 placement: Option<BadgePlacement>,
31}
32
33impl Badge {
34 fn common<F>(cx: &mut Context, content: F) -> Handle<Self>
35 where
36 F: FnOnce(&mut Context),
37 {
38 Self { placement: None }.build(cx, content).bind(
39 Badge::placement,
40 |mut handle, placement| {
41 if let Some(placement) = placement.get(&handle) {
42 let (t, b) = match placement {
43 BadgePlacement::TopLeft | BadgePlacement::TopRight => {
44 (Stretch(1.0), Percentage(85.35))
45 }
46 BadgePlacement::Top => (Stretch(1.0), Percentage(100.0)),
47 BadgePlacement::Bottom => (Percentage(100.0), Stretch(1.0)),
48 BadgePlacement::BottomLeft | BadgePlacement::BottomRight => {
49 (Percentage(85.35), Stretch(1.0))
50 }
51
52 BadgePlacement::Left | BadgePlacement::Right => {
53 (Stretch(1.0), Stretch(1.0))
54 }
55 };
56
57 let (l, r) = match placement {
58 BadgePlacement::TopLeft | BadgePlacement::BottomLeft => {
59 (Stretch(1.0), Percentage(85.35))
60 }
61 BadgePlacement::TopRight | BadgePlacement::BottomRight => {
62 (Percentage(85.35), Stretch(1.0))
63 }
64 BadgePlacement::Left => (Stretch(1.0), Percentage(100.0)),
65 BadgePlacement::Right => (Percentage(100.0), Stretch(1.0)),
66 BadgePlacement::Top | BadgePlacement::Bottom => {
67 (Stretch(1.0), Stretch(1.0))
68 }
69 };
70
71 handle = handle.top(t).bottom(b).left(l).right(r);
72
73 let translate = match placement {
74 BadgePlacement::TopLeft => (Percentage(50.0), Percentage(50.0)),
75 BadgePlacement::Top => (Percentage(0.0), Percentage(50.0)),
76 BadgePlacement::TopRight => (Percentage(-50.0), Percentage(50.0)),
77 BadgePlacement::BottomLeft => (Percentage(50.0), Percentage(-50.0)),
78 BadgePlacement::Bottom => (Percentage(0.0), Percentage(-50.0)),
79 BadgePlacement::BottomRight => (Percentage(-50.0), Percentage(-50.0)),
80 BadgePlacement::Left => (Percentage(50.0), Percentage(0.0)),
81 BadgePlacement::Right => (Percentage(-50.0), Percentage(0.0)),
82 };
83 handle.translate(translate);
84 }
85 },
86 )
87 }
88
89 pub fn empty(cx: &mut Context) -> Handle<Self> {
100 Self::common(cx, |_| {})
101 }
102
103 pub fn new<F, V>(cx: &mut Context, content: F) -> Handle<Self>
114 where
115 F: FnOnce(&mut Context) -> Handle<V>,
116 V: View,
117 {
118 Self::common(cx, |cx| {
119 (content)(cx);
120 })
121 }
122}
123
124impl View for Badge {
125 fn element(&self) -> Option<&'static str> {
126 Some("badge")
127 }
128}
129
130impl Handle<'_, Badge> {
131 pub fn placement<U: Into<BadgePlacement>>(self, placement: impl Res<U>) -> Self {
133 self.bind(placement, |handle, val| {
134 let placement = val.get(&handle).into();
135 handle.modify(|badge| badge.placement = Some(placement));
136 })
137 }
138}