diff --git a/egui_demo_lib/src/apps/demo/toggle_switch.rs b/egui_demo_lib/src/apps/demo/toggle_switch.rs index 307422bd..0dd05bc0 100644 --- a/egui_demo_lib/src/apps/demo/toggle_switch.rs +++ b/egui_demo_lib/src/apps/demo/toggle_switch.rs @@ -92,3 +92,7 @@ fn toggle_ui_compact(ui: &mut egui::Ui, on: &mut bool) -> egui::Response { pub fn toggle(on: &mut bool) -> impl egui::Widget + '_ { move |ui: &mut egui::Ui| toggle_ui(ui, on) } + +pub fn url_to_file_source_code() -> String { + format!("https://github.com/emilk/egui/blob/master/{}", file!()) +} diff --git a/egui_demo_lib/src/apps/demo/widget_gallery.rs b/egui_demo_lib/src/apps/demo/widget_gallery.rs index d48f9e9d..f41dc939 100644 --- a/egui_demo_lib/src/apps/demo/widget_gallery.rs +++ b/egui_demo_lib/src/apps/demo/widget_gallery.rs @@ -47,6 +47,38 @@ impl super::Demo for WidgetGallery { impl super::View for WidgetGallery { fn ui(&mut self, ui: &mut egui::Ui) { + self.gallery(ui); + + ui.separator(); + + ui.vertical_centered(|ui| { + ui.checkbox(&mut self.enabled, "Interactive") + .on_hover_text("Convenient way 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(&mut self, ui: &mut egui::Ui) { + egui::Grid::new("my_grid") + .striped(true) + .spacing([40.0, 4.0]) + .show(ui, |ui| { + self.gallery_grid_contents(ui); + }); + } + + fn gallery_grid_contents(&mut self, ui: &mut egui::Ui) { let Self { enabled, boolean, @@ -56,131 +88,137 @@ impl super::View for WidgetGallery { color, } = self; - ui.horizontal(|ui| { - ui.radio_value(enabled, true, "Enabled"); - ui.radio_value(enabled, false, "Disabled"); - }); ui.set_enabled(*enabled); - ui.separator(); + ui.add(doc_link_label("Label", "label,heading")); + ui.label("Welcome to the widget gallery!"); + ui.end_row(); - let grid = egui::Grid::new("my_grid") - .striped(true) - .spacing([40.0, 4.0]); - grid.show(ui, |ui| { - ui.label("Label:"); - ui.label("Welcome to the widget gallery!"); - ui.end_row(); + ui.add(doc_link_label("Hyperlink", "Hyperlink")); + ui.hyperlink_to(" egui home page", "https://github.com/emilk/egui"); + ui.end_row(); - ui.label("Hyperlink:"); - ui.add(egui::Hyperlink::new("https://github.com/emilk/egui").text(" egui home page")); - 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.label("TextEdit:"); - 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.label("Checkbox:"); - ui.checkbox(boolean, "Checkbox"); - ui.end_row(); + ui.add(doc_link_label("Checkbox", "checkbox")); + ui.checkbox(boolean, "Checkbox"); + ui.end_row(); - ui.label("RadioButton:"); - 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.label("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.label("ComboBox:"); - egui::combo_box_with_label(ui, "Take your pick", format!("{:?}", radio), |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.label("Slider:"); - ui.add(egui::Slider::f32(scalar, 0.0..=100.0).text("value")); - ui.end_row(); - - ui.label("DragValue:"); - ui.add(egui::DragValue::f32(scalar).speed(1.0)); - ui.end_row(); - - ui.label("Color picker:"); - ui.color_edit_button_srgba(color); - ui.end_row(); - - ui.label("Image:"); - ui.image(egui::TextureId::Egui, [24.0, 16.0]) - .on_hover_text("The font texture"); - ui.end_row(); - - ui.label("Button:"); - if ui.button("Toggle boolean").clicked() { - *boolean = !*boolean; - } - ui.end_row(); - - ui.label("ImageButton:"); - if ui - .add(egui::ImageButton::new(egui::TextureId::Egui, [24.0, 16.0])) - .clicked() - { - *boolean = !*boolean; - } - ui.end_row(); - - ui.label("Separator:"); - ui.separator(); - ui.end_row(); - - ui.label("CollapsingHeader:"); - ui.collapsing("Click to see what is hidden!", |ui| { - ui.horizontal_wrapped_for_text(egui::TextStyle::Body, |ui| { - ui.label( - "Not much, as it turns out - but here is a gold star for you for checking:", - ); - ui.colored_label(egui::Color32::GOLD, "☆"); - }); - }); - ui.end_row(); - - ui.label("Custom widget:"); - 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:"); - let n = 512; - let curve = egui::plot::Curve::from_values_iter((0..=n).map(|i| { - use std::f64::consts::TAU; - let x = egui::remap(i as f64, 0.0..=(n as f64), -TAU..=TAU); - egui::plot::Value::new(x, x.sin()) - })); - ui.add( - egui::plot::Plot::default() - .curve(curve) - .height(32.0) - .data_aspect(1.0), - ); - 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.separator(); - ui.vertical_centered(|ui| { - ui.add(crate::__egui_github_link_file!()); + 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("Combo box", "combo_box")); + egui::combo_box_with_label(ui, "Take your pick", format!("{:?}", radio), |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("Slider", "Slider")); + ui.add(egui::Slider::f32(scalar, 0.0..=100.0).text("value")); + ui.end_row(); + + ui.add(doc_link_label("DragValue", "DragValue")); + ui.add(egui::DragValue::f32(scalar).speed(1.0)); + ui.end_row(); + + ui.add(doc_link_label("Color picker", "color_edit")); + ui.color_edit_button_srgba(color); + ui.end_row(); + + ui.add(doc_link_label("Image", "Image")); + ui.image(egui::TextureId::Egui, [24.0, 16.0]) + .on_hover_text("The egui font texture was the convenient choice to show here."); + ui.end_row(); + + ui.add(doc_link_label("ImageButton", "ImageButton")); + if ui + .add(egui::ImageButton::new(egui::TextureId::Egui, [24.0, 16.0])) + .on_hover_text("The egui font texture was the convenient choice to show here.") + .clicked() + { + *boolean = !*boolean; + } + 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_for_text(egui::TextStyle::Body, |ui| { + ui.label( + "Not much, as it turns out - but here is a gold star for you for checking:", + ); + ui.colored_label(egui::Color32::GOLD, "☆"); + }); + }); + ui.end_row(); + + ui.add(doc_link_label("Plot", "plot")); + ui.add(example_plot()); + 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() -> egui::plot::Plot { + let n = 512; + let curve = egui::plot::Curve::from_values_iter((0..=n).map(|i| { + use std::f64::consts::TAU; + let x = egui::remap(i as f64, 0.0..=(n as f64), -TAU..=TAU); + egui::plot::Value::new(x, x.sin()) + })); + egui::plot::Plot::default() + .curve(curve) + .height(32.0) + .data_aspect(1.0) +} + +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); + }); + }) } }