Add some helper functions to Response

This commit is contained in:
Emil Ernerfeldt 2021-03-06 10:48:39 +01:00
parent fb2db4940e
commit 9c8439d053
9 changed files with 67 additions and 40 deletions

View file

@ -57,7 +57,7 @@ pub fn show_tooltip_at_pointer(ctx: &CtxRef, id: Id, add_contents: impl FnOnce(&
let suggested_pos = ctx let suggested_pos = ctx
.input() .input()
.pointer .pointer
.tooltip_pos() .hover_pos()
.map(|pointer_pos| pointer_pos + vec2(16.0, 16.0)); .map(|pointer_pos| pointer_pos + vec2(16.0, 16.0));
show_tooltip_at(ctx, id, suggested_pos, add_contents) show_tooltip_at(ctx, id, suggested_pos, add_contents)
} }

View file

@ -119,7 +119,7 @@ impl CtxRef {
let show_error = |pos: Pos2, text: String| { let show_error = |pos: Pos2, text: String| {
let painter = self.debug_painter(); let painter = self.debug_painter();
let rect = painter.error(pos, text); let rect = painter.error(pos, text);
if let Some(pointer_pos) = self.input.pointer.tooltip_pos() { if let Some(pointer_pos) = self.input.pointer.hover_pos() {
if rect.contains(pointer_pos) { if rect.contains(pointer_pos) {
painter.error( painter.error(
rect.left_bottom() + vec2(2.0, 4.0), rect.left_bottom() + vec2(2.0, 4.0),

View file

@ -407,7 +407,7 @@ impl PointerState {
} }
/// If it is a good idea to show a tooltip, where is pointer? /// If it is a good idea to show a tooltip, where is pointer?
pub fn tooltip_pos(&self) -> Option<Pos2> { pub fn hover_pos(&self) -> Option<Pos2> {
self.latest_pos self.latest_pos
} }

View file

@ -1,5 +1,5 @@
use crate::{ use crate::{
emath::{lerp, Align, Pos2, Rect}, emath::{lerp, Align, Pos2, Rect, Vec2},
PointerButton, NUM_POINTER_BUTTONS, PointerButton, NUM_POINTER_BUTTONS,
}; };
use crate::{CtxRef, Id, LayerId, Sense, Ui}; use crate::{CtxRef, Id, LayerId, Sense, Ui};
@ -118,6 +118,11 @@ impl Response {
self.clicked[PointerButton::Primary as usize] self.clicked[PointerButton::Primary as usize]
} }
/// Returns true if this widget was clicked this frame by the given button.
pub fn clicked_by(&self, button: PointerButton) -> bool {
self.clicked[button as usize]
}
/// Returns true if this widget was clicked this frame by the secondary mouse button (e.g. the right mouse button). /// Returns true if this widget was clicked this frame by the secondary mouse button (e.g. the right mouse button).
pub fn secondary_clicked(&self) -> bool { pub fn secondary_clicked(&self) -> bool {
self.clicked[PointerButton::Secondary as usize] self.clicked[PointerButton::Secondary as usize]
@ -133,6 +138,16 @@ impl Response {
self.double_clicked[PointerButton::Primary as usize] self.double_clicked[PointerButton::Primary as usize]
} }
/// Returns true if this widget was double-clicked this frame by the given button.
pub fn double_clicked_by(&self, button: PointerButton) -> bool {
self.double_clicked[button as usize]
}
/// `true` if there was a click *outside* this widget this frame.
pub fn clicked_elsewhere(&self) -> bool {
!self.hovered && self.ctx.input().pointer.any_pressed()
}
/// Was the widget enabled? /// Was the widget enabled?
/// If false, there was no interaction attempted /// If false, there was no interaction attempted
/// and the widget should be drawn in a gray disabled look. /// and the widget should be drawn in a gray disabled look.
@ -175,6 +190,10 @@ impl Response {
self.dragged self.dragged
} }
pub fn dragged_by(&self, button: PointerButton) -> bool {
self.dragged() && self.ctx.input().pointer.button_down(button)
}
/// Did a drag on this widgets begin this frame? /// Did a drag on this widgets begin this frame?
pub fn drag_started(&self) -> bool { pub fn drag_started(&self) -> bool {
self.dragged && self.ctx.input().pointer.any_pressed() self.dragged && self.ctx.input().pointer.any_pressed()
@ -185,14 +204,13 @@ impl Response {
self.drag_released self.drag_released
} }
/// Returns true if this widget was clicked this frame by the given button. /// If dragged, how many points were we dragged and in what direction?
pub fn clicked_by(&self, button: PointerButton) -> bool { pub fn drag_delta(&self) -> Vec2 {
self.clicked[button as usize] if self.dragged() {
} self.ctx.input().pointer.delta()
} else {
/// Returns true if this widget was double-clicked this frame by the given button. Vec2::ZERO
pub fn double_clicked_by(&self, button: PointerButton) -> bool { }
self.double_clicked[button as usize]
} }
/// Where the pointer (mouse/touch) were when when this widget was clicked or dragged. /// Where the pointer (mouse/touch) were when when this widget was clicked or dragged.
@ -201,6 +219,16 @@ impl Response {
self.interact_pointer_pos self.interact_pointer_pos
} }
/// If it is a good idea to show a tooltip, where is pointer?
/// None if the pointer is outside the response area.
pub fn hover_pos(&self) -> Option<Pos2> {
if self.hovered() {
self.ctx.input().pointer.hover_pos()
} else {
None
}
}
/// Is the pointer button currently down on this widget? /// Is the pointer button currently down on this widget?
/// This is true if the pointer is pressing down or dragging a widget /// This is true if the pointer is pressing down or dragging a widget
pub fn is_pointer_button_down_on(&self) -> bool { pub fn is_pointer_button_down_on(&self) -> bool {

View file

@ -251,7 +251,7 @@ impl<'a> Widget for DragValue<'a> {
ui.memory().request_kb_focus(kb_edit_id); ui.memory().request_kb_focus(kb_edit_id);
ui.memory().drag_value.edit_string = None; // Filled in next frame ui.memory().drag_value.edit_string = None; // Filled in next frame
} else if response.dragged() { } else if response.dragged() {
let mdelta = ui.input().pointer.delta(); let mdelta = response.drag_delta();
let delta_points = mdelta.x - mdelta.y; // Increase to the right and up let delta_points = mdelta.x - mdelta.y; // Increase to the right and up
let delta_value = delta_points as f64 * speed; let delta_value = delta_points as f64 * speed;
if delta_value != 0.0 { if delta_value != 0.0 {

View file

@ -582,10 +582,8 @@ impl Prepared {
} }
} }
if response.hovered() { if let Some(pointer) = response.hover_pos() {
if let Some(pointer) = ui.input().pointer.tooltip_pos() { self.hover(ui, pointer, &mut shapes);
self.hover(ui, pointer, &mut shapes);
}
} }
ui.painter().sub_region(self.rect).extend(shapes); ui.painter().sub_region(self.rect).extend(shapes);

View file

@ -341,7 +341,7 @@ impl<'t> TextEdit<'t> {
paint_cursor_end(ui, response.rect.min, &galley, &cursor_at_pointer); paint_cursor_end(ui, response.rect.min, &galley, &cursor_at_pointer);
} }
if response.hovered() && response.double_clicked() { if response.double_clicked() {
// Select word: // Select word:
let center = cursor_at_pointer; let center = cursor_at_pointer;
let ccursorp = select_word_at(text, center.ccursor); let ccursorp = select_word_at(text, center.ccursor);
@ -371,8 +371,7 @@ impl<'t> TextEdit<'t> {
} }
} }
if ui.input().pointer.any_pressed() && !response.hovered() { if response.clicked_elsewhere() {
// User clicked somewhere else
ui.memory().surrender_kb_focus(id); ui.memory().surrender_kb_focus(id);
} }

View file

@ -255,8 +255,12 @@ impl super::View for InputTest {
if response.double_clicked_by(button) { if response.double_clicked_by(button) {
new_info += &format!("Double-clicked by {:?}\n", button); new_info += &format!("Double-clicked by {:?}\n", button);
} }
if response.dragged() && ui.input().pointer.button_down(button) { if response.dragged_by(button) {
new_info += &format!("Dragged by {:?}\n", button); new_info += &format!(
"Dragged by {:?}, delta: {:?}\n",
button,
response.drag_delta()
);
} }
} }
if !new_info.is_empty() { if !new_info.is_empty() {

View file

@ -84,24 +84,22 @@ impl FrameHistory {
let color = ui.visuals().text_color(); let color = ui.visuals().text_color();
let line_stroke = Stroke::new(1.0, color); let line_stroke = Stroke::new(1.0, color);
if let Some(pointer_pos) = ui.input().pointer.tooltip_pos() { if let Some(pointer_pos) = response.hover_pos() {
if rect.contains(pointer_pos) { let y = pointer_pos.y;
let y = pointer_pos.y; shapes.push(Shape::line_segment(
shapes.push(Shape::line_segment( [pos2(rect.left(), y), pos2(rect.right(), y)],
[pos2(rect.left(), y), pos2(rect.right(), y)], line_stroke,
line_stroke, ));
)); let cpu_usage = to_screen.inverse().transform_pos(pointer_pos).y;
let cpu_usage = to_screen.inverse().transform_pos(pointer_pos).y; let text = format!("{:.1} ms", 1e3 * cpu_usage);
let text = format!("{:.1} ms", 1e3 * cpu_usage); shapes.push(Shape::text(
shapes.push(Shape::text( ui.fonts(),
ui.fonts(), pos2(rect.left(), y),
pos2(rect.left(), y), egui::Align2::LEFT_BOTTOM,
egui::Align2::LEFT_BOTTOM, text,
text, TextStyle::Monospace,
TextStyle::Monospace, color,
color, ));
));
}
} }
let circle_color = color; let circle_color = color;