#[derive(Debug, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] enum Enum { First, Second, Third, } /// Shows off one example of each major type of widget. #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] pub struct WidgetGallery { enabled: bool, visible: bool, boolean: bool, radio: Enum, scalar: f32, string: String, color: egui::Color32, animate_progress_bar: bool, #[cfg(feature = "chrono")] #[cfg_attr(feature = "serde", serde(skip))] date: Option, #[cfg_attr(feature = "serde", serde(skip))] texture: Option, } impl Default for WidgetGallery { fn default() -> Self { Self { enabled: true, visible: true, boolean: false, radio: Enum::First, scalar: 42.0, string: Default::default(), color: egui::Color32::LIGHT_BLUE.linear_multiply(0.5), animate_progress_bar: false, #[cfg(feature = "chrono")] date: None, texture: None, } } } impl super::Demo for WidgetGallery { fn name(&self) -> &'static str { "🗄 Widget Gallery" } fn show(&mut self, ctx: &egui::Context, open: &mut bool) { egui::Window::new(self.name()) .open(open) .resizable(true) .default_width(280.0) .show(ctx, |ui| { use super::View as _; self.ui(ui); }); } } impl super::View for WidgetGallery { fn ui(&mut self, ui: &mut egui::Ui) { ui.add_enabled_ui(self.enabled, |ui| { ui.set_visible(self.visible); egui::Grid::new("my_grid") .num_columns(2) .spacing([40.0, 4.0]) .striped(true) .show(ui, |ui| { self.gallery_grid_contents(ui); }); }); ui.separator(); ui.horizontal(|ui| { ui.checkbox(&mut self.visible, "Visible") .on_hover_text("Uncheck to hide all the widgets."); if self.visible { ui.checkbox(&mut self.enabled, "Interactive") .on_hover_text("Uncheck to inspect how the widgets look when disabled."); } }); ui.separator(); ui.vertical_centered(|ui| { let tooltip_text = "The full egui documentation.\nYou can also click the different widgets names in the left column."; ui.hyperlink("https://docs.rs/egui/").on_hover_text(tooltip_text); ui.add(crate::egui_github_link_file!( "Source code of the widget gallery" )); }); } } impl WidgetGallery { fn gallery_grid_contents(&mut self, ui: &mut egui::Ui) { let Self { enabled: _, visible: _, boolean, radio, scalar, string, color, animate_progress_bar, #[cfg(feature = "chrono")] date, texture, } = self; let texture: &egui::TextureHandle = texture.get_or_insert_with(|| { ui.ctx() .load_texture("example", egui::ColorImage::example(), Default::default()) }); ui.add(doc_link_label("Label", "label,heading")); ui.label("Welcome to the widget gallery!"); ui.end_row(); ui.add(doc_link_label("Hyperlink", "Hyperlink")); use egui::special_emojis::GITHUB; ui.hyperlink_to( format!("{} egui on GitHub", GITHUB), "https://github.com/emilk/egui", ); ui.end_row(); ui.add(doc_link_label("TextEdit", "TextEdit,text_edit")); ui.add(egui::TextEdit::singleline(string).hint_text("Write something here")); ui.end_row(); ui.add(doc_link_label("Button", "button")); if ui.button("Click me!").clicked() { *boolean = !*boolean; } ui.end_row(); ui.add(doc_link_label("Link", "link")); if ui.link("Click me!").clicked() { *boolean = !*boolean; } ui.end_row(); ui.add(doc_link_label("Checkbox", "checkbox")); ui.checkbox(boolean, "Checkbox"); ui.end_row(); ui.add(doc_link_label("RadioButton", "radio")); ui.horizontal(|ui| { ui.radio_value(radio, Enum::First, "First"); ui.radio_value(radio, Enum::Second, "Second"); ui.radio_value(radio, Enum::Third, "Third"); }); ui.end_row(); ui.add(doc_link_label( "SelectableLabel", "selectable_value,SelectableLabel", )); ui.horizontal(|ui| { ui.selectable_value(radio, Enum::First, "First"); ui.selectable_value(radio, Enum::Second, "Second"); ui.selectable_value(radio, Enum::Third, "Third"); }); ui.end_row(); ui.add(doc_link_label("ComboBox", "ComboBox")); egui::ComboBox::from_label("Take your pick") .selected_text(format!("{:?}", radio)) .show_ui(ui, |ui| { ui.style_mut().wrap = Some(false); ui.set_min_width(60.0); ui.selectable_value(radio, Enum::First, "First"); ui.selectable_value(radio, Enum::Second, "Second"); ui.selectable_value(radio, Enum::Third, "Third"); }); ui.end_row(); ui.add(doc_link_label("Slider", "Slider")); ui.add(egui::Slider::new(scalar, 0.0..=360.0).suffix("°")); ui.end_row(); ui.add(doc_link_label("DragValue", "DragValue")); ui.add(egui::DragValue::new(scalar).speed(1.0)); ui.end_row(); ui.add(doc_link_label("ProgressBar", "ProgressBar")); let progress = *scalar / 360.0; let progress_bar = egui::ProgressBar::new(progress) .show_percentage() .animate(*animate_progress_bar); *animate_progress_bar = ui .add(progress_bar) .on_hover_text("The progress bar can be animated!") .hovered(); ui.end_row(); ui.add(doc_link_label("Color picker", "color_edit")); ui.color_edit_button_srgba(color); ui.end_row(); let img_size = 16.0 * texture.size_vec2() / texture.size_vec2().y; ui.add(doc_link_label("Image", "Image")); ui.image(texture, img_size); ui.end_row(); ui.add(doc_link_label("ImageButton", "ImageButton")); if ui.add(egui::ImageButton::new(texture, img_size)).clicked() { *boolean = !*boolean; } ui.end_row(); #[cfg(feature = "chrono")] { let date = date.get_or_insert_with(|| chrono::offset::Utc::now().date_naive()); ui.add(doc_link_label("DatePickerButton", "DatePickerButton")); ui.add(egui_extras::DatePickerButton::new(date)); ui.end_row(); } ui.add(doc_link_label("Separator", "separator")); ui.separator(); ui.end_row(); ui.add(doc_link_label("CollapsingHeader", "collapsing")); ui.collapsing("Click to see what is hidden!", |ui| { ui.horizontal_wrapped(|ui| { ui.spacing_mut().item_spacing.x = 0.0; ui.label("It's a "); ui.add(doc_link_label("Spinner", "spinner")); ui.add_space(4.0); ui.add(egui::Spinner::new()); }); }); ui.end_row(); ui.add(doc_link_label("Plot", "plot")); example_plot(ui); ui.end_row(); ui.hyperlink_to( "Custom widget:", super::toggle_switch::url_to_file_source_code(), ); 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(); } } fn example_plot(ui: &mut egui::Ui) -> egui::Response { use egui::plot::{Line, PlotPoints}; let n = 128; let line_points: PlotPoints = (0..=n) .map(|i| { use std::f64::consts::TAU; let x = egui::remap(i as f64, 0.0..=n as f64, -TAU..=TAU); [x, x.sin()] }) .collect(); let line = Line::new(line_points); egui::plot::Plot::new("example_plot") .height(32.0) .data_aspect(1.0) .show(ui, |plot_ui| plot_ui.line(line)) .response } fn doc_link_label<'a>(title: &'a str, search_term: &'a str) -> impl egui::Widget + 'a { let label = format!("{}:", title); let url = format!("https://docs.rs/egui?search={}", search_term); move |ui: &mut egui::Ui| { ui.hyperlink_to(label, url).on_hover_ui(|ui| { ui.horizontal_wrapped(|ui| { ui.label("Search egui docs for"); ui.code(search_term); }); }) } }