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
.input()
.pointer
.tooltip_pos()
.hover_pos()
.map(|pointer_pos| pointer_pos + vec2(16.0, 16.0));
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 painter = self.debug_painter();
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) {
painter.error(
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?
pub fn tooltip_pos(&self) -> Option<Pos2> {
pub fn hover_pos(&self) -> Option<Pos2> {
self.latest_pos
}

View file

@ -1,5 +1,5 @@
use crate::{
emath::{lerp, Align, Pos2, Rect},
emath::{lerp, Align, Pos2, Rect, Vec2},
PointerButton, NUM_POINTER_BUTTONS,
};
use crate::{CtxRef, Id, LayerId, Sense, Ui};
@ -118,6 +118,11 @@ impl Response {
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).
pub fn secondary_clicked(&self) -> bool {
self.clicked[PointerButton::Secondary as usize]
@ -133,6 +138,16 @@ impl Response {
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?
/// If false, there was no interaction attempted
/// and the widget should be drawn in a gray disabled look.
@ -175,6 +190,10 @@ impl Response {
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?
pub fn drag_started(&self) -> bool {
self.dragged && self.ctx.input().pointer.any_pressed()
@ -185,14 +204,13 @@ impl Response {
self.drag_released
}
/// 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 double-clicked this frame by the given button.
pub fn double_clicked_by(&self, button: PointerButton) -> bool {
self.double_clicked[button as usize]
/// If dragged, how many points were we dragged and in what direction?
pub fn drag_delta(&self) -> Vec2 {
if self.dragged() {
self.ctx.input().pointer.delta()
} else {
Vec2::ZERO
}
}
/// Where the pointer (mouse/touch) were when when this widget was clicked or dragged.
@ -201,6 +219,16 @@ impl Response {
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?
/// This is true if the pointer is pressing down or dragging a widget
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().drag_value.edit_string = None; // Filled in next frame
} 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_value = delta_points as f64 * speed;
if delta_value != 0.0 {

View file

@ -582,10 +582,8 @@ impl Prepared {
}
}
if response.hovered() {
if let Some(pointer) = ui.input().pointer.tooltip_pos() {
self.hover(ui, pointer, &mut shapes);
}
if let Some(pointer) = response.hover_pos() {
self.hover(ui, pointer, &mut 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);
}
if response.hovered() && response.double_clicked() {
if response.double_clicked() {
// Select word:
let center = cursor_at_pointer;
let ccursorp = select_word_at(text, center.ccursor);
@ -371,8 +371,7 @@ impl<'t> TextEdit<'t> {
}
}
if ui.input().pointer.any_pressed() && !response.hovered() {
// User clicked somewhere else
if response.clicked_elsewhere() {
ui.memory().surrender_kb_focus(id);
}

View file

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

View file

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