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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
use crate::*;
mod button;
pub mod color_picker;
pub(crate) mod drag_value;
mod hyperlink;
mod image;
mod label;
pub mod plot;
mod progress_bar;
mod selected_label;
mod separator;
mod slider;
mod spinner;
pub mod text_edit;
pub use button::*;
pub use drag_value::DragValue;
pub use hyperlink::*;
pub use image::Image;
pub use label::*;
pub use progress_bar::ProgressBar;
pub use selected_label::SelectableLabel;
pub use separator::Separator;
pub use slider::*;
pub use spinner::*;
pub use text_edit::{TextBuffer, TextEdit};
#[must_use = "You should put this widget in an ui with `ui.add(widget);`"]
pub trait Widget {
fn ui(self, ui: &mut Ui) -> Response;
}
impl<F> Widget for F
where
F: FnOnce(&mut Ui) -> Response,
{
fn ui(self, ui: &mut Ui) -> Response {
self(ui)
}
}
pub trait WidgetWithState {
type State;
}
pub fn reset_button<T: Default + PartialEq>(ui: &mut Ui, value: &mut T) {
reset_button_with(ui, value, T::default());
}
pub fn reset_button_with<T: PartialEq>(ui: &mut Ui, value: &mut T, reset_value: T) {
if ui
.add_enabled(*value != reset_value, Button::new("Reset"))
.clicked()
{
*value = reset_value;
}
}
pub fn stroke_ui(ui: &mut crate::Ui, stroke: &mut epaint::Stroke, text: &str) {
let epaint::Stroke { width, color } = stroke;
ui.horizontal(|ui| {
ui.add(DragValue::new(width).speed(0.1).clamp_range(0.0..=5.0))
.on_hover_text("Width");
ui.color_edit_button_srgba(color);
ui.label(text);
let (_id, stroke_rect) = ui.allocate_space(ui.spacing().interact_size);
let left = stroke_rect.left_center();
let right = stroke_rect.right_center();
ui.painter().line_segment([left, right], (*width, *color));
});
}
pub(crate) fn shadow_ui(ui: &mut Ui, shadow: &mut epaint::Shadow, text: &str) {
let epaint::Shadow { extrusion, color } = shadow;
ui.horizontal(|ui| {
ui.label(text);
ui.add(
DragValue::new(extrusion)
.speed(1.0)
.clamp_range(0.0..=100.0),
)
.on_hover_text("Extrusion");
ui.color_edit_button_srgba(color);
});
}
pub fn global_dark_light_mode_switch(ui: &mut Ui) {
let style: crate::Style = (*ui.ctx().style()).clone();
let new_visuals = style.visuals.light_dark_small_toggle_button(ui);
if let Some(visuals) = new_visuals {
ui.ctx().set_visuals(visuals);
}
}
pub fn global_dark_light_mode_buttons(ui: &mut Ui) {
let mut visuals = ui.ctx().style().visuals.clone();
visuals.light_dark_radio_buttons(ui);
ui.ctx().set_visuals(visuals);
}