
* Add Spacing::combo_width * Put ComboBox arrow closer to the text * Tweak faint_bg_color * Make it possible to have buttons without background …while still having background for sliders, checkboxes, etc * Rename mandatory_bg_fill -> bg_fill * tweak grid stripe color (again) * Make the animated part of the ProgressBar more visible * Add line in changelog * Add another line in changelog * Menu fix: use the `open` widget style for open menus * Adjust sizes on menu buttons and regular buttons to make sure they match * Update comment Co-authored-by: Andreas Reich <andreas@rerun.io> * optional_bg_fill -> weak_bg_fill Co-authored-by: Andreas Reich <andreas@rerun.io>
290 lines
8.9 KiB
Rust
290 lines
8.9 KiB
Rust
#[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<chrono::NaiveDate>,
|
|
|
|
#[cfg_attr(feature = "serde", serde(skip))]
|
|
texture: Option<egui::TextureHandle>,
|
|
}
|
|
|
|
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);
|
|
});
|
|
})
|
|
}
|
|
}
|