impl<F> Widget for F where F: FnOnce(&mut Ui) -> Response
This enables functions that return `impl Widget`, so that you can create a widget by just returning a lambda from a function. For instance: `ui.add(toggle(bool))` (instead of `toggle(ui, bool)`)
This commit is contained in:
parent
6fe70e685b
commit
040553da78
4 changed files with 62 additions and 48 deletions
|
@ -506,10 +506,10 @@ impl Spacing {
|
|||
tooltip_width,
|
||||
} = self;
|
||||
|
||||
ui_slider_vec2(ui, item_spacing, 0.0..=10.0, "item_spacing");
|
||||
ui_slider_vec2(ui, window_padding, 0.0..=10.0, "window_padding");
|
||||
ui_slider_vec2(ui, button_padding, 0.0..=10.0, "button_padding");
|
||||
ui_slider_vec2(ui, interact_size, 0.0..=60.0, "interact_size")
|
||||
ui.add(slider_vec2(item_spacing, 0.0..=10.0, "item_spacing"));
|
||||
ui.add(slider_vec2(window_padding, 0.0..=10.0, "window_padding"));
|
||||
ui.add(slider_vec2(button_padding, 0.0..=10.0, "button_padding"));
|
||||
ui.add(slider_vec2(interact_size, 0.0..=60.0, "interact_size"))
|
||||
.on_hover_text("Minimum size of an interactive widget");
|
||||
ui.add(Slider::f32(indent, 0.0..=100.0).text("indent"));
|
||||
ui.add(Slider::f32(slider_width, 0.0..=1000.0).text("slider_width"));
|
||||
|
@ -694,39 +694,21 @@ impl Visuals {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: improve and standardize ui_slider_vec2
|
||||
fn ui_slider_vec2(
|
||||
ui: &mut Ui,
|
||||
value: &mut Vec2,
|
||||
// TODO: improve and standardize `slider_vec2`
|
||||
fn slider_vec2<'a>(
|
||||
value: &'a mut Vec2,
|
||||
range: std::ops::RangeInclusive<f32>,
|
||||
text: &str,
|
||||
) -> Response {
|
||||
text: &'a str,
|
||||
) -> impl Widget + 'a {
|
||||
move |ui: &mut crate::Ui| {
|
||||
ui.horizontal(|ui| {
|
||||
/*
|
||||
let fsw = full slider_width
|
||||
let ssw = small slider_width
|
||||
let space = item_spacing.x
|
||||
let value = interact_size.x;
|
||||
|
||||
fsw + space + value = ssw + space + value + space + ssw + space + value
|
||||
fsw + space + value = 2 * ssw + 3 * space + 2 * value
|
||||
fsw + space - value = 2 * ssw + 3 * space
|
||||
fsw - 2 * space - value = 2 * ssw
|
||||
ssw = fsw / 2 - space - value / 2
|
||||
*/
|
||||
// let spacing = &ui.spacing();
|
||||
// let space = spacing.item_spacing.x;
|
||||
// let value_w = spacing.interact_size.x;
|
||||
// let full_slider_width = spacing.slider_width;
|
||||
// let small_slider_width = full_slider_width / 2.0 - space - value_w / 2.0;
|
||||
// ui.spacing_mut().slider_width = small_slider_width;
|
||||
|
||||
ui.add(Slider::f32(&mut value.x, range.clone()).text("w"));
|
||||
ui.add(Slider::f32(&mut value.y, range.clone()).text("h"));
|
||||
ui.label(text);
|
||||
})
|
||||
.response
|
||||
}
|
||||
}
|
||||
|
||||
fn ui_color(ui: &mut Ui, srgba: &mut Color32, text: &str) {
|
||||
ui.horizontal(|ui| {
|
||||
|
|
|
@ -35,6 +35,31 @@ pub trait Widget {
|
|||
fn ui(self, ui: &mut Ui) -> Response;
|
||||
}
|
||||
|
||||
/// This enables functions that return `impl Widget`, so that you can
|
||||
/// create a widget by just returning a lambda from a function.
|
||||
///
|
||||
/// For instance: `ui.add(slider_vec2(&mut vec2));` with:
|
||||
///
|
||||
/// ```
|
||||
/// pub fn slider_vec2(value: &mut egui::Vec2) -> impl egui::Widget + '_ {
|
||||
/// move |ui: &mut egui::Ui| {
|
||||
/// ui.horizontal(|ui| {
|
||||
/// ui.add(egui::Slider::f32(&mut value.x, 0.0..=1.0).text("x"));
|
||||
/// ui.add(egui::Slider::f32(&mut value.y, 0.0..=1.0).text("y"));
|
||||
/// })
|
||||
/// .response
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
impl<F> Widget for F
|
||||
where
|
||||
F: FnOnce(&mut Ui) -> Response,
|
||||
{
|
||||
fn ui(self, ui: &mut Ui) -> Response {
|
||||
self(ui)
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/// Show a button to reset a value to its default.
|
||||
|
|
|
@ -9,7 +9,12 @@
|
|||
/// | |.......|
|
||||
/// \_______\_____/
|
||||
/// ```
|
||||
pub fn toggle(ui: &mut egui::Ui, on: &mut bool) -> egui::Response {
|
||||
///
|
||||
/// ## Example:
|
||||
/// ``` ignore
|
||||
/// toggle_ui(ui, &mut my_bool);
|
||||
/// ```
|
||||
pub fn toggle_ui(ui: &mut egui::Ui, on: &mut bool) -> egui::Response {
|
||||
// Widget code can be broken up in four steps:
|
||||
// 1. Decide a size for the widget
|
||||
// 2. Allocate space for it
|
||||
|
@ -58,7 +63,7 @@ pub fn toggle(ui: &mut egui::Ui, on: &mut bool) -> egui::Response {
|
|||
|
||||
/// Here is the same code again, but a bit more compact:
|
||||
#[allow(dead_code)]
|
||||
fn toggle_compact(ui: &mut egui::Ui, on: &mut bool) -> egui::Response {
|
||||
fn toggle_ui_compact(ui: &mut egui::Ui, on: &mut bool) -> egui::Response {
|
||||
let desired_size = ui.spacing().interact_size.y * egui::vec2(2.0, 1.0);
|
||||
let (rect, response) = ui.allocate_exact_size(desired_size, egui::Sense::click());
|
||||
*on ^= response.clicked(); // toggle if clicked
|
||||
|
@ -77,14 +82,13 @@ fn toggle_compact(ui: &mut egui::Ui, on: &mut bool) -> egui::Response {
|
|||
response
|
||||
}
|
||||
|
||||
pub fn demo(ui: &mut egui::Ui, on: &mut bool) {
|
||||
ui.horizontal_wrapped_for_text(egui::TextStyle::Button, |ui| {
|
||||
toggle(ui, on).on_hover_text("Click to toggle");
|
||||
ui.add(crate::__egui_github_link_file!());
|
||||
})
|
||||
.response
|
||||
.on_hover_text(
|
||||
"It's easy to create your own widgets!\n\
|
||||
This toggle switch is just one function and 15 lines of code.",
|
||||
);
|
||||
// A wrapper that allows the more idiomatic usage pattern: `ui.add(toggle(&mut my_bool))`
|
||||
/// iOS-style toggle switch.
|
||||
///
|
||||
/// ## Example:
|
||||
/// ``` ignore
|
||||
/// ui.add(toggle(&mut my_bool));
|
||||
/// ```
|
||||
pub fn toggle(on: &mut bool) -> impl egui::Widget + '_ {
|
||||
move |ui: &mut egui::Ui| toggle_ui(ui, on)
|
||||
}
|
||||
|
|
|
@ -156,7 +156,10 @@ impl super::View for WidgetGallery {
|
|||
ui.end_row();
|
||||
|
||||
ui.label("Custom widget:");
|
||||
super::toggle_switch::demo(ui, boolean);
|
||||
ui.add(super::toggle_switch::toggle(boolean)).on_hover_text(
|
||||
"It's easy to create your own widgets!\n\
|
||||
This toggle switch is just 15 lines of code.",
|
||||
);
|
||||
ui.end_row();
|
||||
|
||||
ui.label("Plot:");
|
||||
|
|
Loading…
Reference in a new issue