perspective_viewer/components/
render_warning.rsuse yew::prelude::*;
use super::style::LocalStyle;
use crate::renderer::*;
use crate::session::*;
use crate::utils::*;
use crate::*;
#[derive(Properties)]
pub struct RenderWarningProps {
pub dimensions: Option<(usize, usize, Option<usize>, Option<usize>)>,
pub renderer: Renderer,
pub session: Session,
}
impl PartialEq for RenderWarningProps {
fn eq(&self, other: &Self) -> bool {
self.dimensions == other.dimensions
}
}
pub enum RenderWarningMsg {
DismissWarning,
}
pub struct RenderWarning {
col_warn: Option<(usize, usize)>,
row_warn: Option<(usize, usize)>,
}
impl RenderWarning {
fn update_warnings(&mut self, ctx: &Context<Self>) {
if let Some((num_cols, num_rows, max_cols, max_rows)) = ctx.props().dimensions {
let count = num_cols * num_rows;
if max_cols.map_or(false, |x| x < num_cols) {
self.col_warn = Some((max_cols.unwrap(), num_cols));
} else {
self.col_warn = None;
}
if max_rows.map_or(false, |x| x < num_rows) {
self.row_warn = Some((num_cols * max_rows.unwrap(), count));
} else {
self.row_warn = None;
}
} else {
self.col_warn = None;
self.row_warn = None;
}
}
}
impl Component for RenderWarning {
type Message = RenderWarningMsg;
type Properties = RenderWarningProps;
fn create(ctx: &Context<Self>) -> Self {
let mut elem = Self {
col_warn: None,
row_warn: None,
};
elem.update_warnings(ctx);
elem
}
fn update(&mut self, ctx: &Context<Self>, msg: Self::Message) -> bool {
match msg {
RenderWarningMsg::DismissWarning => {
clone!(ctx.props().renderer, ctx.props().session);
ApiFuture::spawn(async move {
renderer.disable_active_plugin_render_warning();
renderer.update(&session).await
});
},
};
true
}
fn changed(&mut self, ctx: &Context<Self>, _old: &Self::Properties) -> bool {
self.update_warnings(ctx);
true
}
fn view(&self, ctx: &Context<Self>) -> Html {
if self.col_warn.is_some() || self.row_warn.is_some() {
let warning = match (self.col_warn, self.row_warn) {
(Some((x, y)), Some((a, b))) => html! {
<span style="white-space:nowrap">
{ "Rendering" }
{ render_pair(x, y) }
{ "of columns and" }
{ render_pair(a, b) }
{ "of points." }
</span>
},
(Some((x, y)), None) => html! {
<span style="white-space:nowrap">
{ "Rendering" }
{ render_pair(x, y) }
{ "of columns." }
</span>
},
(None, Some((x, y))) => html! {
<span style="white-space:nowrap">
{ "Rendering" }
{ render_pair(x, y) }
{ "of points." }
</span>
},
_ => html! { <div /> },
};
let onclick = ctx.link().callback(|_| RenderWarningMsg::DismissWarning);
html! {
<>
<LocalStyle href={css!("render-warning")} />
<div
class="plugin_information plugin_information--warning"
id="plugin_information--size"
>
<span class="plugin_information__icon" />
<span class="plugin_information__text" id="plugin_information_count">
{ warning }
</span>
<span class="plugin_information__actions">
<span class="plugin_information__action" onmousedown={onclick}>
{ "Render all points" }
</span>
</span>
</div>
</>
}
} else {
html! {}
}
}
}
fn pretty_print_int(i: usize) -> String {
let mut s = String::new();
let i_str = i.to_string();
let a = i_str.chars().rev().enumerate();
for (idx, val) in a {
if idx != 0 && idx % 3 == 0 {
s.insert(0, ',');
}
s.insert(0, val);
}
s
}
fn render_pair(n: usize, d: usize) -> Html {
let x = pretty_print_int(n);
let y = pretty_print_int(d);
let total = ((n as f64 / d as f64) * 100_f64).floor() as usize;
html! {
<span title={format!("${} / ${}", x, y)} class="plugin_information--overflow-hint">
{ "\u{00a0}" }
<span class="plugin_information--overflow-hint-percent">{ format!("{}%", total) }</span>
{ "\u{00a0}" }
</span>
}
}