Add ui.drag_angle helper
This commit is contained in:
parent
d4c0197752
commit
5df9bfd514
4 changed files with 57 additions and 8 deletions
|
@ -416,6 +416,7 @@ struct Widgets {
|
|||
count: usize,
|
||||
radio: usize,
|
||||
slider_value: f32,
|
||||
angle: f32,
|
||||
single_line_text_input: String,
|
||||
multiline_text_input: String,
|
||||
}
|
||||
|
@ -427,6 +428,7 @@ impl Default for Widgets {
|
|||
radio: 0,
|
||||
count: 0,
|
||||
slider_value: 3.4,
|
||||
angle: TAU / 8.0,
|
||||
single_line_text_input: "Hello World!".to_owned(),
|
||||
multiline_text_input: "Text can both be so wide that it needs a line break, but you can also add manual line break by pressing enter, creating new paragraphs.\nThis is the start of the next paragraph.\n\nClick me to edit me!".to_owned(),
|
||||
}
|
||||
|
@ -480,6 +482,15 @@ impl Widgets {
|
|||
}
|
||||
}
|
||||
ui.separator();
|
||||
{
|
||||
ui.label("An angle stored as radians, but edited in degrees:");
|
||||
ui.horizontal_centered(|ui| {
|
||||
ui.style_mut().item_spacing.x = 0.0;
|
||||
ui.drag_angle(&mut self.angle);
|
||||
ui.label(format!(" = {} radians", self.angle));
|
||||
});
|
||||
}
|
||||
ui.separator();
|
||||
|
||||
ui.horizontal(|ui| {
|
||||
ui.add(label!("Single line text input:"));
|
||||
|
|
|
@ -211,6 +211,7 @@ impl Font {
|
|||
font.add_char(c);
|
||||
}
|
||||
font.add_char(REPLACEMENT_CHAR);
|
||||
font.add_char('°');
|
||||
|
||||
font
|
||||
}
|
||||
|
|
|
@ -506,6 +506,22 @@ impl Ui {
|
|||
pub fn separator(&mut self) -> GuiResponse {
|
||||
self.add(Separator::new())
|
||||
}
|
||||
|
||||
/// Modify an angle. The given angle should be in radians, but is shown to the user in degrees.
|
||||
/// The angle is NOT wrapped, so the user may select, for instance 720° = 2𝞃 = 4π
|
||||
pub fn drag_angle(&mut self, radians: &mut f32) -> GuiResponse {
|
||||
#![allow(clippy::float_cmp)]
|
||||
|
||||
let mut degrees = radians.to_degrees();
|
||||
let response = self.add(DragValue::f32(&mut degrees).speed(1.0).suffix("°"));
|
||||
|
||||
// only touch `*radians` if we actually changed the degree value
|
||||
if degrees != radians.to_degrees() {
|
||||
*radians = degrees.to_radians();
|
||||
}
|
||||
|
||||
response
|
||||
}
|
||||
}
|
||||
|
||||
/// # Adding Containers / Sub-uis:
|
||||
|
|
|
@ -552,11 +552,18 @@ impl Widget for Separator {
|
|||
pub struct DragValue<'a> {
|
||||
value: &'a mut f32,
|
||||
speed: f32,
|
||||
prefix: String,
|
||||
suffix: String,
|
||||
}
|
||||
|
||||
impl<'a> DragValue<'a> {
|
||||
pub fn f32(value: &'a mut f32) -> Self {
|
||||
DragValue { value, speed: 1.0 }
|
||||
DragValue {
|
||||
value,
|
||||
speed: 1.0,
|
||||
prefix: Default::default(),
|
||||
suffix: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
/// How much the value changes when dragged one point (logical pixel).
|
||||
|
@ -564,16 +571,30 @@ impl<'a> DragValue<'a> {
|
|||
self.speed = speed;
|
||||
self
|
||||
}
|
||||
|
||||
/// Show a prefix before the number, e.g. "x: "
|
||||
pub fn prefix(mut self, prefix: impl ToString) -> Self {
|
||||
self.prefix = prefix.to_string();
|
||||
self
|
||||
}
|
||||
|
||||
/// Add a suffix to the number, this can be e.g. a unit ("°" or " m")
|
||||
pub fn suffix(mut self, suffix: impl ToString) -> Self {
|
||||
self.suffix = suffix.to_string();
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Widget for DragValue<'a> {
|
||||
fn ui(self, ui: &mut Ui) -> InteractInfo {
|
||||
let Self { value, speed } = self;
|
||||
let speed_in_physical_pixels = speed / ui.input().pixels_per_point;
|
||||
let precision = (1.0 / speed_in_physical_pixels.abs())
|
||||
.log10()
|
||||
.ceil()
|
||||
.max(0.0) as usize;
|
||||
let Self {
|
||||
value,
|
||||
speed,
|
||||
prefix,
|
||||
suffix,
|
||||
} = self;
|
||||
let aim_rad = ui.input().physical_pixel_size(); // ui.input().aim_radius(); // TODO
|
||||
let precision = (aim_rad / speed.abs()).log10().ceil().max(0.0) as usize;
|
||||
let value_text = format_with_minimum_precision(*value, precision);
|
||||
|
||||
let kb_edit_id = ui.make_position_id().with("edit");
|
||||
|
@ -602,7 +623,7 @@ impl<'a> Widget for DragValue<'a> {
|
|||
}
|
||||
response.into()
|
||||
} else {
|
||||
let button = Button::new(value_text)
|
||||
let button = Button::new(format!("{}{}{}", prefix, value_text, suffix))
|
||||
.sense(Sense::click_and_drag())
|
||||
.text_style(TextStyle::Monospace);
|
||||
let response = ui.add(button);
|
||||
|
|
Loading…
Reference in a new issue