[drag-value] click on a DragValue to edit it

This commit is contained in:
Emil Ernerfeldt 2020-08-28 14:35:39 +02:00
parent f3bbb210c0
commit 48e42ff6a5
2 changed files with 56 additions and 24 deletions

View file

@ -570,21 +570,53 @@ 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_with_minimum_precision(*value, precision)) let value_text = format_with_minimum_precision(*value, precision);
.sense(Sense::drag())
.text_style(TextStyle::Monospace); let kb_edit_id = ui.make_position_id().with("edit");
let interact = ui.add(button); let is_kb_editing = ui.memory().has_kb_focus(kb_edit_id);
if interact.active {
let mdelta = ui.input().mouse.delta; if is_kb_editing {
let delta_points = mdelta.x - mdelta.y; // Increase to the right and up let mut value_text = ui
let delta_value = speed * delta_points; .memory()
if delta_value != 0.0 { .temp_edit_string
*value += delta_value; .take()
*value = round_to_precision(*value, precision); .unwrap_or_else(|| value_text);
// TODO: To make use or `smart_aim` for `DragValue` we need to store some state somewhere, let response = ui.add(
// otherwise we will just keep rounding to the same value while moving the mouse. TextEdit::new(&mut value_text)
.id(kb_edit_id)
.multiline(false)
.text_style(TextStyle::Monospace),
);
if let Ok(parsed_value) = value_text.parse() {
*value = parsed_value;
} }
if ui.input().key_pressed(Key::Enter) {
ui.memory().surrender_kb_focus(kb_edit_id);
} else {
ui.memory().temp_edit_string = Some(value_text);
}
response.into()
} else {
let button = Button::new(value_text)
.sense(Sense::click_and_drag())
.text_style(TextStyle::Monospace);
let response = ui.add(button);
// response.tooltip_text("Drag to edit, click to enter a value"); // TODO: may clash with users own tooltips
if response.clicked {
ui.memory().request_kb_focus(kb_edit_id);
ui.memory().temp_edit_string = None; // Filled in next frame
} else if response.active {
let mdelta = ui.input().mouse.delta;
let delta_points = mdelta.x - mdelta.y; // Increase to the right and up
let delta_value = speed * delta_points;
if delta_value != 0.0 {
*value += delta_value;
*value = round_to_precision(*value, precision);
// TODO: To make use or `smart_aim` for `DragValue` we need to store some state somewhere,
// otherwise we will just keep rounding to the same value while moving the mouse.
}
}
response.into()
} }
interact.into()
} }
} }

View file

@ -192,21 +192,21 @@ impl<'a> Slider<'a> {
.text_color(text_color), .text_color(text_color),
); );
let edit_id = self.id.expect("We should have an id by now").with("edit"); let kb_edit_id = self.id.expect("We should have an id by now").with("edit");
let is_editing = ui.memory().has_kb_focus(edit_id); let is_kb_editing = ui.memory().has_kb_focus(kb_edit_id);
let aim_radius = ui.input().aim_radius(); let aim_radius = ui.input().aim_radius();
let mut value_text = self.format_value(aim_radius, x_range); let value_text = self.format_value(aim_radius, x_range);
if is_editing { if is_kb_editing {
value_text = ui let mut value_text = ui
.memory() .memory()
.temp_edit_string .temp_edit_string
.take() .take()
.unwrap_or_else(|| value_text); .unwrap_or_else(|| value_text);
ui.add( ui.add(
TextEdit::new(&mut value_text) TextEdit::new(&mut value_text)
.id(edit_id) .id(kb_edit_id)
.multiline(false) .multiline(false)
.text_color(text_color) .text_color(text_color)
.text_style(TextStyle::Monospace), .text_style(TextStyle::Monospace),
@ -215,7 +215,7 @@ impl<'a> Slider<'a> {
self.set_value_f32(value); self.set_value_f32(value);
} }
if ui.input().key_pressed(Key::Enter) { if ui.input().key_pressed(Key::Enter) {
ui.memory().surrender_kb_focus(edit_id); ui.memory().surrender_kb_focus(kb_edit_id);
} else { } else {
ui.memory().temp_edit_string = Some(value_text); ui.memory().temp_edit_string = Some(value_text);
} }
@ -226,10 +226,10 @@ impl<'a> Slider<'a> {
.text_color(text_color) .text_color(text_color)
.text_style(TextStyle::Monospace), .text_style(TextStyle::Monospace),
); );
response.tooltip_text("Click to edit"); response.tooltip_text("Click to enter a value");
let response = ui.interact(response.rect, edit_id, Sense::click()); let response = ui.interact(response.rect, kb_edit_id, Sense::click());
if response.clicked { if response.clicked {
ui.memory().request_kb_focus(edit_id); ui.memory().request_kb_focus(kb_edit_id);
ui.memory().temp_edit_string = None; // Filled in next frame ui.memory().temp_edit_string = None; // Filled in next frame
} }
} }