Add Id to Response

This commit is contained in:
Emil Ernerfeldt 2020-12-26 11:19:39 +01:00
parent a2ab35bab8
commit 66ae0ed7b9
8 changed files with 54 additions and 45 deletions

View file

@ -19,6 +19,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
* You can now easily constrain Egui to a portion of the screen using `RawInput::screen_rect`. * You can now easily constrain Egui to a portion of the screen using `RawInput::screen_rect`.
* You can now control the minimum and maixumum number of decimals to show in a `Slider` or `DragValue`. * You can now control the minimum and maixumum number of decimals to show in a `Slider` or `DragValue`.
* Add `egui::math::Rot2`: rotation helper. * Add `egui::math::Rot2`: rotation helper.
* `Response` now contains the `Id` of the widget it pertains to.
### Changed 🔧 ### Changed 🔧
@ -44,6 +45,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Deprecated ### Deprecated
* `RawInput::screen_size` - use `RawInput::screen_rect` instead. * `RawInput::screen_size` - use `RawInput::screen_rect` instead.
* left/centered/right column functions on `Ui`. * left/centered/right column functions on `Ui`.
* `ui.interact_hover` and `ui.hovered`.
## 0.5.0 - 2020-12-13 ## 0.5.0 - 2020-12-13

View file

@ -172,10 +172,11 @@ impl Prepared {
state.size = content_ui.min_rect().size(); state.size = content_ui.min_rect().size();
let interact_id = if movable { let interact_id = layer_id.id.with("move");
Some(layer_id.id.with("move")) let sense = if movable {
Sense::click_and_drag()
} else { } else {
None Sense::click() // allow clicks to bring to front
}; };
let move_response = ctx.interact( let move_response = ctx.interact(
@ -184,16 +185,16 @@ impl Prepared {
ctx.style().spacing.item_spacing, ctx.style().spacing.item_spacing,
state.rect(), state.rect(),
interact_id, interact_id,
Sense::click_and_drag(), sense,
); );
if move_response.active { if move_response.active && movable {
state.pos += ctx.input().mouse.delta; state.pos += ctx.input().mouse.delta;
} }
state.pos = ctx.constrain_window_rect(state.rect()).min; state.pos = ctx.constrain_window_rect(state.rect()).min;
if move_response.active if (move_response.active || move_response.clicked)
|| mouse_pressed_on_area(ctx, layer_id) || mouse_pressed_on_area(ctx, layer_id)
|| !ctx.memory().areas.visible_last_frame(&layer_id) || !ctx.memory().areas.visible_last_frame(&layer_id)
{ {

View file

@ -44,7 +44,7 @@ impl SidePanel {
}); });
let panel_rect = panel_ui.min_rect(); let panel_rect = panel_ui.min_rect();
let response = panel_ui.interact_hover(panel_rect); let response = panel_ui.interact(panel_rect, id, Sense::hover());
ctx.frame_state().allocate_left_panel(panel_rect); ctx.frame_state().allocate_left_panel(panel_rect);
@ -94,7 +94,7 @@ impl TopPanel {
}); });
let panel_rect = panel_ui.min_rect(); let panel_rect = panel_ui.min_rect();
let response = panel_ui.interact_hover(panel_rect); let response = panel_ui.interact(panel_rect, id, Sense::hover());
ctx.frame_state().allocate_top_panel(panel_rect); ctx.frame_state().allocate_top_panel(panel_rect);
@ -132,7 +132,8 @@ impl CentralPanel {
}); });
let panel_rect = panel_ui.min_rect(); let panel_rect = panel_ui.min_rect();
let response = panel_ui.interact_hover(panel_rect); let id = Id::new("central_panel");
let response = panel_ui.interact(panel_rect, id, Sense::hover());
ctx.frame_state().allocate_central_panel(panel_rect); ctx.frame_state().allocate_central_panel(panel_rect);

View file

@ -200,25 +200,24 @@ impl CtxRef {
clip_rect: Rect, clip_rect: Rect,
item_spacing: Vec2, item_spacing: Vec2,
rect: Rect, rect: Rect,
id: Option<Id>, id: Id,
sense: Sense, sense: Sense,
) -> Response { ) -> Response {
let interact_rect = rect.expand2((0.5 * item_spacing).min(Vec2::splat(5.0))); // make it easier to click let interact_rect = rect.expand2((0.5 * item_spacing).min(Vec2::splat(5.0))); // make it easier to click
let hovered = self.contains_mouse(layer_id, clip_rect, interact_rect); let hovered = self.contains_mouse(layer_id, clip_rect, interact_rect);
let has_kb_focus = id.map(|id| self.memory().has_kb_focus(id)).unwrap_or(false); let has_kb_focus = self.memory().has_kb_focus(id);
// If the the focus is lost after the call to interact, // If the the focus is lost after the call to interact,
// this will be `false`, so `TextEdit` also sets this manually. // this will be `false`, so `TextEdit` also sets this manually.
let lost_kb_focus = id let lost_kb_focus = self.memory().lost_kb_focus(id);
.map(|id| self.memory().lost_kb_focus(id))
.unwrap_or(false);
if id.is_none() || sense == Sense::hover() || !layer_id.allow_interaction() { if sense == Sense::hover() || !layer_id.allow_interaction() {
// Not interested or allowed input: // Not interested or allowed input:
return Response { return Response {
ctx: self.clone(), ctx: self.clone(),
sense, id,
rect, rect,
sense,
hovered, hovered,
clicked: false, clicked: false,
double_clicked: false, double_clicked: false,
@ -227,7 +226,6 @@ impl CtxRef {
lost_kb_focus, lost_kb_focus,
}; };
} }
let id = id.unwrap();
self.register_interaction_id(id, rect.min); self.register_interaction_id(id, rect.min);
@ -243,8 +241,9 @@ impl CtxRef {
if hovered { if hovered {
let mut response = Response { let mut response = Response {
ctx: self.clone(), ctx: self.clone(),
sense, id,
rect, rect,
sense,
hovered: true, hovered: true,
clicked: false, clicked: false,
double_clicked: false, double_clicked: false,
@ -274,8 +273,9 @@ impl CtxRef {
// miss // miss
Response { Response {
ctx: self.clone(), ctx: self.clone(),
sense, id,
rect, rect,
sense,
hovered, hovered,
clicked: false, clicked: false,
double_clicked: false, double_clicked: false,
@ -288,8 +288,9 @@ impl CtxRef {
let clicked = hovered && active && self.input.mouse.could_be_click; let clicked = hovered && active && self.input.mouse.could_be_click;
Response { Response {
ctx: self.clone(), ctx: self.clone(),
sense, id,
rect, rect,
sense,
hovered, hovered,
clicked, clicked,
double_clicked: clicked && self.input.mouse.double_click, double_clicked: clicked && self.input.mouse.double_click,
@ -300,8 +301,9 @@ impl CtxRef {
} else if self.input.mouse.down { } else if self.input.mouse.down {
Response { Response {
ctx: self.clone(), ctx: self.clone(),
sense, id,
rect, rect,
sense,
hovered: hovered && active, hovered: hovered && active,
clicked: false, clicked: false,
double_clicked: false, double_clicked: false,
@ -312,8 +314,9 @@ impl CtxRef {
} else { } else {
Response { Response {
ctx: self.clone(), ctx: self.clone(),
sense, id,
rect, rect,
sense,
hovered, hovered,
clicked: false, clicked: false,
double_clicked: false, double_clicked: false,

View file

@ -50,8 +50,8 @@ pub fn drop_target<R>(
let mut content_ui = ui.child_ui(inner_rect, *ui.layout()); let mut content_ui = ui.child_ui(inner_rect, *ui.layout());
let ret = body(&mut content_ui); let ret = body(&mut content_ui);
let outer_rect = Rect::from_min_max(outer_rect_bounds.min, content_ui.min_rect().max + margin); let outer_rect = Rect::from_min_max(outer_rect_bounds.min, content_ui.min_rect().max + margin);
let (id, outer_rect) = ui.allocate_space(outer_rect.size());
let response = ui.interact_hover(outer_rect); let response = ui.interact(outer_rect, id, Sense::hover());
let style = if is_being_dragged && can_accept_what_is_being_dragged && response.hovered { let style = if is_being_dragged && can_accept_what_is_being_dragged && response.hovered {
ui.style().visuals.widgets.active ui.style().visuals.widgets.active
@ -73,8 +73,6 @@ pub fn drop_target<R>(
}, },
); );
ui.allocate_space(outer_rect.size());
(ret, response) (ret, response)
} }

View file

@ -1,4 +1,4 @@
use crate::{math::Rect, CtxRef, Ui}; use crate::{math::Rect, CtxRef, Id, Ui};
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -58,6 +58,9 @@ pub struct Response {
pub ctx: CtxRef, pub ctx: CtxRef,
// IN: // IN:
/// The `Id` of the widget/area this response pertains.
pub id: Id,
/// The area of the screen we are talking about /// The area of the screen we are talking about
pub rect: Rect, pub rect: Rect,
@ -91,6 +94,7 @@ impl std::fmt::Debug for Response {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let Self { let Self {
ctx: _, ctx: _,
id,
rect, rect,
sense, sense,
hovered, hovered,
@ -101,6 +105,7 @@ impl std::fmt::Debug for Response {
lost_kb_focus, lost_kb_focus,
} = self; } = self;
f.debug_struct("Response") f.debug_struct("Response")
.field("id", id)
.field("rect", rect) .field("rect", rect)
.field("sense", sense) .field("sense", sense)
.field("hovered", hovered) .field("hovered", hovered)
@ -144,6 +149,7 @@ impl Response {
assert!(self.ctx == other.ctx); assert!(self.ctx == other.ctx);
Self { Self {
ctx: other.ctx, ctx: other.ctx,
id: self.id,
rect: self.rect.union(other.rect), rect: self.rect.union(other.rect),
sense: self.sense.union(other.sense), sense: self.sense.union(other.sense),
hovered: self.hovered || other.hovered, hovered: self.hovered || other.hovered,

View file

@ -386,24 +386,19 @@ impl Ui {
self.clip_rect(), self.clip_rect(),
self.style().spacing.item_spacing, self.style().spacing.item_spacing,
rect, rect,
Some(id), id,
sense, sense,
) )
} }
#[deprecated = "Use: interact(rect, id, Sense::hover())"]
pub fn interact_hover(&self, rect: Rect) -> Response { pub fn interact_hover(&self, rect: Rect) -> Response {
self.ctx().interact( self.interact(rect, self.auto_id_with("hover_rect"), Sense::hover())
self.layer_id(),
self.clip_rect(),
self.style().spacing.item_spacing,
rect,
None,
Sense::hover(),
)
} }
#[deprecated = "Use: contains_mouse()"]
pub fn hovered(&self, rect: Rect) -> bool { pub fn hovered(&self, rect: Rect) -> bool {
self.interact_hover(rect).hovered self.interact(rect, self.id, Sense::hover()).hovered
} }
pub fn contains_mouse(&self, rect: Rect) -> bool { pub fn contains_mouse(&self, rect: Rect) -> bool {
@ -477,7 +472,8 @@ impl Ui {
} }
} }
let id = Id::new(self.next_auto_id); // TODO: increment counter here self.next_auto_id = self.next_auto_id.wrapping_add(1);
let id = Id::new(self.next_auto_id);
(id, rect) (id, rect)
} }
@ -499,15 +495,17 @@ impl Ui {
); );
self.region.expand_to_include_rect(inner_child_rect); self.region.expand_to_include_rect(inner_child_rect);
self.next_auto_id = self.next_auto_id.wrapping_add(1);
inner_child_rect inner_child_rect
} }
pub(crate) fn advance_cursor_after_rect(&mut self, rect: Rect) { pub(crate) fn advance_cursor_after_rect(&mut self, rect: Rect) -> Id {
let item_spacing = self.style().spacing.item_spacing; let item_spacing = self.style().spacing.item_spacing;
self.layout self.layout
.advance_after_outer_rect(&mut self.region, rect, rect, item_spacing); .advance_after_outer_rect(&mut self.region, rect, rect, item_spacing);
self.region.expand_to_include_rect(rect); self.region.expand_to_include_rect(rect);
self.next_auto_id = self.next_auto_id.wrapping_add(1);
Id::new(self.next_auto_id)
} }
pub(crate) fn cursor(&self) -> Pos2 { pub(crate) fn cursor(&self) -> Pos2 {
@ -541,7 +539,7 @@ impl Ui {
); );
self.region.expand_to_include_rect(final_child_rect); self.region.expand_to_include_rect(final_child_rect);
let response = self.interact_hover(final_child_rect); let response = self.interact(final_child_rect, child_ui.id, Sense::hover());
(ret, response) (ret, response)
} }
@ -1029,7 +1027,7 @@ impl Ui {
self.layout self.layout
.advance_after_outer_rect(&mut self.region, rect, rect, item_spacing); .advance_after_outer_rect(&mut self.region, rect, rect, item_spacing);
self.region.expand_to_include_rect(rect); self.region.expand_to_include_rect(rect);
(ret, self.interact_hover(rect)) (ret, self.interact(rect, child_ui.id, Sense::hover()))
} }
/// Temporarily split split an Ui into several columns. /// Temporarily split split an Ui into several columns.

View file

@ -162,8 +162,8 @@ impl Widget for Label {
assert!(!galley.rows.is_empty(), "Galleys are never empty"); assert!(!galley.rows.is_empty(), "Galleys are never empty");
let rect = galley.rows[0].rect().translate(vec2(pos.x, pos.y)); let rect = galley.rows[0].rect().translate(vec2(pos.x, pos.y));
ui.advance_cursor_after_rect(rect); let id = ui.advance_cursor_after_rect(rect);
let mut total_response = ui.interact_hover(rect); let mut total_response = ui.interact(rect, id, Sense::hover());
let mut y_translation = 0.0; let mut y_translation = 0.0;
if let Some(row) = galley.rows.get(1) { if let Some(row) = galley.rows.get(1) {
@ -179,7 +179,7 @@ impl Widget for Label {
row.y_max += y_translation; row.y_max += y_translation;
let rect = row.rect().translate(vec2(pos.x, pos.y)); let rect = row.rect().translate(vec2(pos.x, pos.y));
ui.advance_cursor_after_rect(rect); ui.advance_cursor_after_rect(rect);
total_response |= ui.interact_hover(rect); total_response |= ui.interact(rect, id, Sense::hover());
} }
self.paint_galley(ui, pos, galley); self.paint_galley(ui, pos, galley);