[drag-value] show full precision if needed

This commit is contained in:
Emil Ernerfeldt 2020-08-28 00:22:08 +02:00
parent ecb703a696
commit ec1e8b9966
4 changed files with 20 additions and 16 deletions

View file

@ -404,13 +404,13 @@ impl Widgets {
}); });
ui.add(Slider::f32(&mut self.slider_value, -10.0..=10.0).text("value")); ui.add(Slider::f32(&mut self.slider_value, -10.0..=10.0).text("value"));
if ui.add(Button::new("Double it")).clicked {
self.slider_value *= 2.0;
}
ui.horizontal(|ui| { ui.horizontal(|ui| {
ui.label("drag this number:"); ui.label("drag this number:");
ui.add(DragValue::f32(&mut self.slider_value).speed(0.01)); ui.add(DragValue::f32(&mut self.slider_value).speed(0.01));
}); });
if ui.add(Button::new("Assign PI")).clicked {
self.slider_value = std::f32::consts::PI;
}
ui.horizontal(|ui| { ui.horizontal(|ui| {
ui.add(label!("Single line text input:")); ui.add(label!("Single line text input:"));

View file

@ -83,3 +83,16 @@ pub fn round_to_precision(value: f32, decimal_places: usize) -> f32 {
.parse() .parse()
.unwrap_or_else(|_| value) .unwrap_or_else(|_| value)
} }
pub fn format_with_minimum_precision(value: f32, precision: usize) -> String {
let text = format!("{:.*}", precision, value);
if (text.parse::<f32>().unwrap() - value).abs() <= std::f32::EPSILON {
// Enough precision to show the value accurately - good!
text
} else {
// The value has more precision than we expected.
// Probably the value was set not by the slider, but from outside.
// In any case: show the full value
value.to_string()
}
}

View file

@ -96,7 +96,7 @@ impl Label {
// TODO: this should return a LabelLayout which has a paint method. // TODO: this should return a LabelLayout which has a paint method.
// We can then split Widget::Ui in two: layout + allocating space, and painting. // We can then split Widget::Ui in two: layout + allocating space, and painting.
// this allows us to assemble lables, THEN detect interaction, THEN chose color style based on that. // this allows us to assemble labels, THEN detect interaction, THEN chose color style based on that.
// pub fn layout(self, ui: &mut ui) -> LabelLayout { } // pub fn layout(self, ui: &mut ui) -> LabelLayout { }
// TODO: a paint method for painting anywhere in a ui. // TODO: a paint method for painting anywhere in a ui.
@ -570,7 +570,7 @@ impl<'a> Widget for DragValue<'a> {
.log10() .log10()
.ceil() .ceil()
.max(0.0) as usize; .max(0.0) as usize;
let button = Button::new(format!("{:.*}", precision, *value)) let button = Button::new(format_with_minimum_precision(*value, precision))
.sense(Sense::drag()) .sense(Sense::drag())
.text_style(TextStyle::Monospace); .text_style(TextStyle::Monospace);
let interact = ui.add(button); let interact = ui.add(button);

View file

@ -184,7 +184,7 @@ impl<'a> Slider<'a> {
fn text_ui(&mut self, ui: &mut Ui, x_range: RangeInclusive<f32>) { fn text_ui(&mut self, ui: &mut Ui, x_range: RangeInclusive<f32>) {
let aim_radius = ui.input().aim_radius(); let aim_radius = ui.input().aim_radius();
let value_text = self.format_value(aim_radius, x_range); let value_text = self.format_value(aim_radius, x_range);
let label_text = self.text.as_ref().map(String::as_str).unwrap_or_default(); let label_text = self.text.as_deref().unwrap_or_default();
let text = format!("{}: {}", label_text, value_text); let text = format!("{}: {}", label_text, value_text);
let text_color = self.text_color.unwrap_or_else(|| ui.style().text_color); let text_color = self.text_color.unwrap_or_else(|| ui.style().text_color);
ui.add(Label::new(text).multiline(false).text_color(text_color)); ui.add(Label::new(text).multiline(false).text_color(text_color));
@ -203,16 +203,7 @@ impl<'a> Slider<'a> {
(-range.log10()).ceil().max(0.0) as usize (-range.log10()).ceil().max(0.0) as usize
}); });
let text = format!("{:.*}", precision, value); format_with_minimum_precision(value, precision)
if (text.parse::<f32>().unwrap() - value).abs() <= std::f32::EPSILON {
// Enough precision to show the value accurately - good!
text
} else {
// The value has more precision than we expected.
// Probably the value was set not by the slider, but from outside.
// In any case: show the full value
value.to_string()
}
} }
} }