diff --git a/docs/demo_web.js b/docs/demo_web.js index cbee3b9c..acef4227 100644 --- a/docs/demo_web.js +++ b/docs/demo_web.js @@ -212,28 +212,28 @@ function makeMutClosure(arg0, arg1, dtor, f) { return real; } -function __wbg_adapter_24(arg0, arg1) { - wasm._dyn_core__ops__function__FnMut_____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__hf394391f07d20fc8(arg0, arg1); +function __wbg_adapter_24(arg0, arg1, arg2) { + wasm._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h1fcacf2ad60d2387(arg0, arg1, addHeapObject(arg2)); } -function __wbg_adapter_27(arg0, arg1) { - wasm._dyn_core__ops__function__FnMut_____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h74e3475b1fcd9cd1(arg0, arg1); +function __wbg_adapter_27(arg0, arg1, arg2) { + wasm._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h1fcacf2ad60d2387(arg0, arg1, addHeapObject(arg2)); } -function __wbg_adapter_30(arg0, arg1, arg2) { - wasm._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h8ac16b787f5fa676(arg0, arg1, addHeapObject(arg2)); +function __wbg_adapter_30(arg0, arg1) { + wasm._dyn_core__ops__function__FnMut_____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h2c9bae79cd8d7906(arg0, arg1); } -function __wbg_adapter_33(arg0, arg1, arg2) { - wasm._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h8ac16b787f5fa676(arg0, arg1, addHeapObject(arg2)); +function __wbg_adapter_33(arg0, arg1) { + wasm._dyn_core__ops__function__FnMut_____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h76852efce6b7a83f(arg0, arg1); } function __wbg_adapter_36(arg0, arg1, arg2) { - wasm._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h8ac16b787f5fa676(arg0, arg1, addHeapObject(arg2)); + wasm._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h1fcacf2ad60d2387(arg0, arg1, addHeapObject(arg2)); } function __wbg_adapter_39(arg0, arg1, arg2) { - wasm._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h8ac16b787f5fa676(arg0, arg1, addHeapObject(arg2)); + wasm._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h1fcacf2ad60d2387(arg0, arg1, addHeapObject(arg2)); } /** @@ -727,30 +727,30 @@ async function init(input) { var ret = wasm.memory; return addHeapObject(ret); }; - imports.wbg.__wbindgen_closure_wrapper366 = function(arg0, arg1, arg2) { - var ret = makeMutClosure(arg0, arg1, 72, __wbg_adapter_27); - return addHeapObject(ret); - }; - imports.wbg.__wbindgen_closure_wrapper364 = function(arg0, arg1, arg2) { - var ret = makeMutClosure(arg0, arg1, 72, __wbg_adapter_39); - return addHeapObject(ret); - }; - imports.wbg.__wbindgen_closure_wrapper368 = function(arg0, arg1, arg2) { - var ret = makeMutClosure(arg0, arg1, 72, __wbg_adapter_33); - return addHeapObject(ret); - }; - imports.wbg.__wbindgen_closure_wrapper361 = function(arg0, arg1, arg2) { - var ret = makeMutClosure(arg0, arg1, 72, __wbg_adapter_24); - return addHeapObject(ret); - }; - imports.wbg.__wbindgen_closure_wrapper370 = function(arg0, arg1, arg2) { + imports.wbg.__wbindgen_closure_wrapper360 = function(arg0, arg1, arg2) { var ret = makeMutClosure(arg0, arg1, 72, __wbg_adapter_30); return addHeapObject(ret); }; - imports.wbg.__wbindgen_closure_wrapper362 = function(arg0, arg1, arg2) { + imports.wbg.__wbindgen_closure_wrapper364 = function(arg0, arg1, arg2) { var ret = makeMutClosure(arg0, arg1, 72, __wbg_adapter_36); return addHeapObject(ret); }; + imports.wbg.__wbindgen_closure_wrapper366 = function(arg0, arg1, arg2) { + var ret = makeMutClosure(arg0, arg1, 72, __wbg_adapter_33); + return addHeapObject(ret); + }; + imports.wbg.__wbindgen_closure_wrapper368 = function(arg0, arg1, arg2) { + var ret = makeMutClosure(arg0, arg1, 72, __wbg_adapter_39); + return addHeapObject(ret); + }; + imports.wbg.__wbindgen_closure_wrapper370 = function(arg0, arg1, arg2) { + var ret = makeMutClosure(arg0, arg1, 72, __wbg_adapter_24); + return addHeapObject(ret); + }; + imports.wbg.__wbindgen_closure_wrapper362 = function(arg0, arg1, arg2) { + var ret = makeMutClosure(arg0, arg1, 72, __wbg_adapter_27); + return addHeapObject(ret); + }; if (typeof input === 'string' || (typeof Request === 'function' && input instanceof Request) || (typeof URL === 'function' && input instanceof URL)) { input = fetch(input); diff --git a/docs/demo_web_bg.wasm b/docs/demo_web_bg.wasm index b7149c22..82ebff31 100644 Binary files a/docs/demo_web_bg.wasm and b/docs/demo_web_bg.wasm differ diff --git a/egui/src/demos.rs b/egui/src/demos.rs index a21f7347..c2edd630 100644 --- a/egui/src/demos.rs +++ b/egui/src/demos.rs @@ -3,6 +3,7 @@ //! The demo-code is also used in benchmarks and tests. mod app; mod fractal_clock; +pub mod toggle_switch; pub use { app::{DemoApp, DemoWindow}, diff --git a/egui/src/demos/app.rs b/egui/src/demos/app.rs index 639b982d..d1d5aafd 100644 --- a/egui/src/demos/app.rs +++ b/egui/src/demos/app.rs @@ -397,6 +397,8 @@ impl DemoWindow { CollapsingHeader::new("Misc") .default_open(false) .show(ui, |ui| { + super::toggle_switch::demo(ui, &mut self.widgets.button_enabled); + ui.horizontal(|ui| { ui.label("You can pretty easily paint your own small icons:"); let painter = ui.canvas(Vec2::splat(16.0)); diff --git a/egui/src/demos/toggle_switch.rs b/egui/src/demos/toggle_switch.rs new file mode 100644 index 00000000..106ee1a8 --- /dev/null +++ b/egui/src/demos/toggle_switch.rs @@ -0,0 +1,65 @@ +//! Source code example of how to create your own widget. +use crate::{paint::PaintCmd, *}; + +// iOS style toggle switch +pub fn toggle(ui: &mut Ui, on: &mut bool) -> Response { + // First we must reserve some space to use: + let desired_size = vec2(2.0, 1.0) * ui.style().clickable_diameter; + let rect = ui.allocate_space(desired_size); + + // Now that we have an area, we want to check for clicks. + // To do that we need an `Id` for the button. + // Id's are best created from unique identifiers (like fixed labels) + // but since we have no label for the switch we here just generate an `Id` automatically + // (based on a rolling counter in the `Ui`). + let id = ui.make_position_id(); + let response = ui.interact(rect, id, Sense::click()); + if response.clicked { + *on = !*on; + } + + // For painting, let's ask for a simple animation from Egui. + // Egui keeps track of changes in the boolean associated with the id and + // returns an animated value between `[0, 1]` for how far along "toggled" we are. + let how_on = ui.ctx().animate_bool(id, *on); + + // After interaction (to avoid frame delay), we paint the widget. + // We can follow the standard style theme by asking + // "how should something that is being interacted with be painted?". + // This gives us visual style change when the user hovers and clicks on the widget. + let style = ui.style().interact(&response); + let off_color = Rgba::new(0.0, 0.0, 0.0, 0.0); + let on_color = Rgba::new(0.0, 0.5, 0.0, 0.5); + // All coordinates are in screen coordinates (not relative) + // so we use `rect` to place the elements. + let radius = 0.5 * rect.height(); + ui.painter().add(PaintCmd::Rect { + rect, + corner_radius: radius, + outline: style.bg_outline, + fill: Some(lerp(off_color..=on_color, how_on).into()), + }); + // Animate the circle from left to right: + let circle_x = lerp((rect.left() + radius)..=(rect.right() - radius), how_on); + ui.painter().add(PaintCmd::Circle { + center: pos2(circle_x, rect.center().y), + radius: 0.75 * radius, + outline: Some(style.line_style()), + fill: Some(style.main_fill), + }); + + // All done! Return the response so the user can check what happened + // (hoovered, clicked, ...) and show a tooltip. + + response +} + +pub fn demo(ui: &mut Ui, on: &mut bool) { + ui.label("Example of how to create your own widget from scratch."); + let url = format!("https://github.com/emilk/egui/blob/master/{}", file!()); + ui.horizontal_centered(|ui| { + ui.label("My beautiful toggle switch:"); + toggle(ui, on).tooltip_text("Click to toggle"); + ui.add(Hyperlink::new(url).text("(source code)")); + }); +}