From 5ba420988f75692412588fbf3ff9b0f904c75bc6 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Fri, 11 Sep 2020 17:17:43 +0200 Subject: [PATCH] [docs] improve toggle_switch.rs demo with better comments --- egui/src/demos/toggle_switch.rs | 52 +++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/egui/src/demos/toggle_switch.rs b/egui/src/demos/toggle_switch.rs index c5893390..9a8477bf 100644 --- a/egui/src/demos/toggle_switch.rs +++ b/egui/src/demos/toggle_switch.rs @@ -1,13 +1,32 @@ //! Source code example of how to create your own widget. +//! This is meant to be read as a tutorial, hence the plethora of comments. use crate::{paint::PaintCmd, *}; -// iOS style toggle switch +/// iOS-style toggle switch: +/// +/// ``` text +/// _____________ +/// / /.....\ +/// | |.......| +/// \_______\_____/ +/// ``` pub fn toggle(ui: &mut Ui, on: &mut bool) -> Response { - // First we must reserve some space to use: + // Widget code can be broken up in four steps: + // 1. Decide a size for the widget + // 2. Allocate space for it + // 3. Handle interactions with the widget (if any) + // 4. Paint the widget + + // 1. Deciding widget size: + // You can query the `ui` how much space is available, + // but in this example we have a fixed size component: let desired_size = vec2(2.0, 1.0) * ui.style().spacing.clickable_diameter; + + // 2. Allocating space: + // This is where we get a region (`Rect`) of the screen assigned. let rect = ui.allocate_space(desired_size); - // Now that we have an area, we want to check for clicks. + // 3. Interact: Time 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 @@ -18,28 +37,26 @@ pub fn toggle(ui: &mut Ui, on: &mut bool) -> Response { *on = !*on; } - // For painting, let's ask for a simple animation from Egui. + // 4. Paint! + // First 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. + // returns an animated value in the 0-1 range for how much "on" 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 + // We will follow the current style 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. + // This will, for instance, give us different colors when the widget is hovered or clicked. let visuals = 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 off_bg_fill = Rgba::new(0.0, 0.0, 0.0, 0.0); + let on_bg_fill = Rgba::new(0.0, 0.5, 0.0, 0.5); + // All coordinates are in absolute screen coordinates so we use `rect` to place the elements. let radius = 0.5 * rect.height(); ui.painter().add(PaintCmd::Rect { rect, corner_radius: radius, - fill: lerp(off_color..=on_color, how_on).into(), + fill: lerp(off_bg_fill..=on_bg_fill, how_on).into(), stroke: visuals.bg_stroke, }); - // Animate the circle from left to right: + // Paint the circle, animating it from left to right with `how_on`: let circle_x = lerp((rect.left() + radius)..=(rect.right() - radius), how_on); ui.painter().add(PaintCmd::Circle { center: pos2(circle_x, rect.center().y), @@ -48,9 +65,8 @@ pub fn toggle(ui: &mut Ui, on: &mut bool) -> Response { stroke: visuals.fg_stroke, }); - // All done! Return the response so the user can check what happened - // (hoovered, clicked, ...) and show a tooltip. - + // All done! Return the interaction response so the user can check what happened + // (hovered, clicked, ...) and maybe show a tooltip: response }