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
128
129
130
131
132
133
134
mod choose_something;
mod colors;
mod lasso;
mod load;
mod popup;
mod prompt_input;
pub(crate) mod screenshot;
mod url;
pub(crate) mod warper;
use anyhow::Result;
pub use choose_something::ChooseSomething;
pub use colors::{ColorLegend, ColorScale, DivergingScale};
pub use lasso::{Lasso, PolyLineLasso};
pub use load::{FileLoader, FutureLoader, RawBytes};
pub use popup::PopupMsg;
pub use prompt_input::PromptInput;
pub use url::URLManager;
use crate::{Color, GfxCtx};
use geom::Polygon;
pub struct Cached<K: PartialEq + Clone, V> {
contents: Option<(K, V)>,
}
impl<K: PartialEq + Clone, V> Cached<K, V> {
pub fn new() -> Cached<K, V> {
Cached { contents: None }
}
pub fn key(&self) -> Option<K> {
self.contents.as_ref().map(|(k, _)| k.clone())
}
pub fn value(&self) -> Option<&V> {
self.contents.as_ref().map(|(_, v)| v)
}
pub fn value_mut(&mut self) -> Option<&mut V> {
self.contents.as_mut().map(|(_, v)| v)
}
pub fn update<F: FnMut(K) -> V>(&mut self, key: Option<K>, mut produce_value: F) {
if let Some(new_key) = key {
if self.key() != Some(new_key.clone()) {
self.contents = Some((new_key.clone(), produce_value(new_key)));
}
} else {
self.contents = None;
}
}
pub fn set(&mut self, key: K, value: V) {
self.contents = Some((key, value));
}
pub fn clear(&mut self) {
self.contents = None;
}
pub fn take(&mut self) -> Option<(K, V)> {
self.contents.take()
}
}
impl<K: PartialEq + Clone, V> Default for Cached<K, V> {
fn default() -> Self {
Cached::new()
}
}
pub fn open_browser<I: AsRef<str>>(url: I) {
let _ = webbrowser::open(url.as_ref());
}
fn grey_out_map(g: &mut GfxCtx) {
g.fork_screenspace();
g.draw_polygon(
Color::BLACK.alpha(0.6),
Polygon::rectangle(g.canvas.window_width, g.canvas.window_height),
);
g.unfork();
}
pub fn set_clipboard(x: String) {
#[cfg(not(target_arch = "wasm32"))]
{
use clipboard::{ClipboardContext, ClipboardProvider};
if let Err(err) =
ClipboardProvider::new().and_then(|mut ctx: ClipboardContext| ctx.set_contents(x))
{
error!("Copying to clipboard broke: {}", err);
}
}
#[cfg(target_arch = "wasm32")]
{
let _ = x;
}
}
pub fn get_clipboard() -> Result<String> {
#[cfg(not(target_arch = "wasm32"))]
{
use clipboard::{ClipboardContext, ClipboardProvider};
let mut ctx: ClipboardContext = match ClipboardProvider::new() {
Ok(ctx) => ctx,
Err(err) => bail!("{}", err),
};
let contents = match ctx.get_contents() {
Ok(contents) => contents,
Err(err) => bail!("{}", err),
};
Ok(contents)
}
#[cfg(target_arch = "wasm32")]
{
bail!("Unsupported on web");
}
}