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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
// ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
// ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
// ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
// ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
// ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
// ┃ Copyright (c) 2017, the Perspective Authors. ┃
// ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
// ┃ This file is part of the Perspective library, distributed under the terms ┃
// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
use yew::prelude::*;
use crate::renderer::limits::RenderLimits;
#[derive(Properties, PartialEq)]
pub struct RenderWarningProps {
pub dimensions: Option<RenderLimits>,
/// Called when the user clicks "Render all points". The parent disables
/// the render warning on the active plugin and re-draws.
pub on_dismiss: Callback<()>,
}
#[function_component(RenderWarning)]
pub fn render_warning(props: &RenderWarningProps) -> Html {
let dimensions = props.dimensions;
let (col_warn, row_warn) = if let Some(limits) = dimensions {
let col_warn = if limits.max_cols.is_some_and(|x| x < limits.num_cols) {
Some((limits.max_cols.unwrap(), limits.num_cols))
} else {
None
};
let row_warn = if limits.max_rows.is_some_and(|x| x < limits.num_rows) {
Some((
limits.num_cols * limits.max_rows.unwrap(),
limits.num_cols * limits.num_rows,
))
} else {
None
};
(col_warn, row_warn)
} else {
(None, None)
};
if col_warn.is_some() || row_warn.is_some() {
let warning = match (col_warn, 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 on_dismiss = props.on_dismiss.clone();
let onclick = Callback::from(move |_: MouseEvent| on_dismiss.emit(()));
html! {
<>
<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>
}
}