perspective_viewer/ui/containers/
scroll_panel_item.rs1use std::cell::Cell;
14use std::rc::Rc;
15
16use yew::prelude::*;
17
18#[derive(PartialEq, Properties)]
19pub struct ScrollPanelItemProps {
20 pub children: Children,
21
22 pub size_hint: f64,
23
24 #[prop_or_default]
25 pub is_debug_mode: bool,
26
27 #[prop_or_default]
28 measured_size: Rc<Cell<Option<f64>>>,
29}
30
31impl ScrollPanelItemProps {
32 pub(crate) fn get_size(&self) -> f64 {
33 if self.is_debug_mode {
34 self.measured_size.get().unwrap_or(self.size_hint)
35 } else {
36 self.size_hint
37 }
38 }
39}
40
41pub struct ScrollPanelItem {
42 node: NodeRef,
43}
44
45impl Component for ScrollPanelItem {
46 type Message = ();
47 type Properties = ScrollPanelItemProps;
48
49 fn create(ctx: &Context<Self>) -> Self {
50 if ctx.props().is_debug_mode {
51 ctx.props().measured_size.set(Some(ctx.props().size_hint));
52 }
53
54 Self {
55 node: NodeRef::default(),
56 }
57 }
58
59 fn view(&self, ctx: &Context<Self>) -> Html {
60 html! {
61 if ctx.props().is_debug_mode {
62 <div class="debug-size-wrapper" style="display: flow-root" ref={self.node.clone()}>
63 for child in ctx.props().children.iter() {
64 { child }
65 }
66 </div>
67 } else {
68 for child in ctx.props().children.iter() {
69 { child }
70 }
71 }
72 }
73 }
74
75 fn changed(&mut self, ctx: &Context<Self>, _old: &Self::Properties) -> bool {
76 if ctx.props().is_debug_mode {
77 ctx.props().measured_size.set(Some(ctx.props().size_hint));
78 }
79
80 true
81 }
82
83 fn rendered(&mut self, ctx: &Context<Self>, first_render: bool) {
84 if first_render && ctx.props().is_debug_mode {
85 let elem = self.node.cast::<web_sys::HtmlElement>().unwrap();
86 let new_height = elem.get_bounding_client_rect().height();
87 if ctx.props().measured_size.get() != Some(new_height) {
88 tracing::warn!(
89 "ScrollPanel size_hint does not match element size: {} != {}",
90 ctx.props().size_hint,
91 new_height
92 );
93 web_sys::console::warn_1(&elem);
94 ctx.props().measured_size.set(Some(new_height));
95 }
96 }
97 }
98}