[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()
.ceil()
.max(0.0) as usize;
let button = Button::new(format_with_minimum_precision(*value, precision))
.sense(Sense::drag())
.text_style(TextStyle::Monospace);
let interact = ui.add(button);
if interact.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.
let value_text = format_with_minimum_precision(*value, precision);
let kb_edit_id = ui.make_position_id().with("edit");
let is_kb_editing = ui.memory().has_kb_focus(kb_edit_id);
if is_kb_editing {
let mut value_text = ui
.memory()
.temp_edit_string
.take()
.unwrap_or_else(|| value_text);
let response = ui.add(
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),
);
let 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 kb_edit_id = self.id.expect("We should have an id by now").with("edit");
let is_kb_editing = ui.memory().has_kb_focus(kb_edit_id);
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 {
value_text = ui
if is_kb_editing {
let mut value_text = ui
.memory()
.temp_edit_string
.take()
.unwrap_or_else(|| value_text);
ui.add(
TextEdit::new(&mut value_text)
.id(edit_id)
.id(kb_edit_id)
.multiline(false)
.text_color(text_color)
.text_style(TextStyle::Monospace),
@ -215,7 +215,7 @@ impl<'a> Slider<'a> {
self.set_value_f32(value);
}
if ui.input().key_pressed(Key::Enter) {
ui.memory().surrender_kb_focus(edit_id);
ui.memory().surrender_kb_focus(kb_edit_id);
} else {
ui.memory().temp_edit_string = Some(value_text);
}
@ -226,10 +226,10 @@ impl<'a> Slider<'a> {
.text_color(text_color)
.text_style(TextStyle::Monospace),
);
response.tooltip_text("Click to edit");
let response = ui.interact(response.rect, edit_id, Sense::click());
response.tooltip_text("Click to enter a value");
let response = ui.interact(response.rect, kb_edit_id, Sense::click());
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
}
}