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,
|
count: usize,
|
||||||
radio: usize,
|
radio: usize,
|
||||||
slider_value: f32,
|
slider_value: f32,
|
||||||
|
angle: f32,
|
||||||
single_line_text_input: String,
|
single_line_text_input: String,
|
||||||
multiline_text_input: String,
|
multiline_text_input: String,
|
||||||
}
|
}
|
||||||
|
@ -427,6 +428,7 @@ impl Default for Widgets {
|
||||||
radio: 0,
|
radio: 0,
|
||||||
count: 0,
|
count: 0,
|
||||||
slider_value: 3.4,
|
slider_value: 3.4,
|
||||||
|
angle: TAU / 8.0,
|
||||||
single_line_text_input: "Hello World!".to_owned(),
|
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(),
|
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.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.horizontal(|ui| {
|
||||||
ui.add(label!("Single line text input:"));
|
ui.add(label!("Single line text input:"));
|
||||||
|
|
|
@ -211,6 +211,7 @@ impl Font {
|
||||||
font.add_char(c);
|
font.add_char(c);
|
||||||
}
|
}
|
||||||
font.add_char(REPLACEMENT_CHAR);
|
font.add_char(REPLACEMENT_CHAR);
|
||||||
|
font.add_char('°');
|
||||||
|
|
||||||
font
|
font
|
||||||
}
|
}
|
||||||
|
|
|
@ -506,6 +506,22 @@ impl Ui {
|
||||||
pub fn separator(&mut self) -> GuiResponse {
|
pub fn separator(&mut self) -> GuiResponse {
|
||||||
self.add(Separator::new())
|
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:
|
/// # Adding Containers / Sub-uis:
|
||||||
|
|
|
@ -552,11 +552,18 @@ impl Widget for Separator {
|
||||||
pub struct DragValue<'a> {
|
pub struct DragValue<'a> {
|
||||||
value: &'a mut f32,
|
value: &'a mut f32,
|
||||||
speed: f32,
|
speed: f32,
|
||||||
|
prefix: String,
|
||||||
|
suffix: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> DragValue<'a> {
|
impl<'a> DragValue<'a> {
|
||||||
pub fn f32(value: &'a mut f32) -> Self {
|
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).
|
/// How much the value changes when dragged one point (logical pixel).
|
||||||
|
@ -564,16 +571,30 @@ impl<'a> DragValue<'a> {
|
||||||
self.speed = speed;
|
self.speed = speed;
|
||||||
self
|
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> {
|
impl<'a> Widget for DragValue<'a> {
|
||||||
fn ui(self, ui: &mut Ui) -> InteractInfo {
|
fn ui(self, ui: &mut Ui) -> InteractInfo {
|
||||||
let Self { value, speed } = self;
|
let Self {
|
||||||
let speed_in_physical_pixels = speed / ui.input().pixels_per_point;
|
value,
|
||||||
let precision = (1.0 / speed_in_physical_pixels.abs())
|
speed,
|
||||||
.log10()
|
prefix,
|
||||||
.ceil()
|
suffix,
|
||||||
.max(0.0) as usize;
|
} = 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 value_text = format_with_minimum_precision(*value, precision);
|
||||||
|
|
||||||
let kb_edit_id = ui.make_position_id().with("edit");
|
let kb_edit_id = ui.make_position_id().with("edit");
|
||||||
|
@ -602,7 +623,7 @@ impl<'a> Widget for DragValue<'a> {
|
||||||
}
|
}
|
||||||
response.into()
|
response.into()
|
||||||
} else {
|
} else {
|
||||||
let button = Button::new(value_text)
|
let button = Button::new(format!("{}{}{}", prefix, value_text, suffix))
|
||||||
.sense(Sense::click_and_drag())
|
.sense(Sense::click_and_drag())
|
||||||
.text_style(TextStyle::Monospace);
|
.text_style(TextStyle::Monospace);
|
||||||
let response = ui.add(button);
|
let response = ui.add(button);
|
||||||
|
|
Loading…
Reference in a new issue