From c23dfd155ceb6b1d8e383af9702f766207be9498 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Sun, 30 Aug 2020 08:52:42 +0200 Subject: [PATCH] [refactor] unify `InteractInfo` and `GuiResponse` to `Response` --- egui/src/containers/area.rs | 12 +-- egui/src/containers/collapsing_header.rs | 44 +++++----- egui/src/containers/popup.rs | 2 +- egui/src/containers/resize.rs | 32 ++++---- egui/src/containers/scroll_area.rs | 18 ++-- egui/src/containers/window.rs | 32 ++++---- egui/src/context.rs | 31 ++++--- egui/src/demos/app.rs | 10 +-- egui/src/menu.rs | 18 ++-- egui/src/style.rs | 13 +-- egui/src/types.rs | 100 +++++------------------ egui/src/ui.rs | 53 ++++-------- egui/src/widgets.rs | 82 +++++++++---------- egui/src/widgets/slider.rs | 32 ++++---- egui/src/widgets/text_edit.rs | 27 +++--- 15 files changed, 212 insertions(+), 294 deletions(-) diff --git a/egui/src/containers/area.rs b/egui/src/containers/area.rs index 295ca74c..4ec5f93d 100644 --- a/egui/src/containers/area.rs +++ b/egui/src/containers/area.rs @@ -140,7 +140,7 @@ impl Area { } } - pub fn show(self, ctx: &Arc, add_contents: impl FnOnce(&mut Ui)) -> InteractInfo { + pub fn show(self, ctx: &Arc, add_contents: impl FnOnce(&mut Ui)) -> Response { let prepared = self.begin(ctx); let mut content_ui = prepared.content_ui(ctx); add_contents(&mut content_ui); @@ -166,7 +166,7 @@ impl Prepared { ) } - pub(crate) fn end(self, ctx: &Arc, content_ui: Ui) -> InteractInfo { + pub(crate) fn end(self, ctx: &Arc, content_ui: Ui) -> Response { let Prepared { layer, mut state, @@ -183,11 +183,11 @@ impl Prepared { } else { None }; - let move_interact = + let move_response = ctx.interact(layer, clip_rect, rect, interact_id, Sense::click_and_drag()); let input = ctx.input(); - if move_interact.active { + if move_response.active { state.pos += input.mouse.delta; state.vel = input.mouse.velocity; } else { @@ -219,7 +219,7 @@ impl Prepared { // &format!("Area size: {:?}", state.size), // ); - if move_interact.active + if move_response.active || mouse_pressed_on_area(ctx, layer) || !ctx.memory().areas.visible_last_frame(&layer) { @@ -228,7 +228,7 @@ impl Prepared { } ctx.memory().areas.set_state(layer, state); - move_interact + move_response } } diff --git a/egui/src/containers/collapsing_header.rs b/egui/src/containers/collapsing_header.rs index 72ff0958..ef3bad4e 100644 --- a/egui/src/containers/collapsing_header.rs +++ b/egui/src/containers/collapsing_header.rs @@ -69,11 +69,11 @@ impl State { } /// Paint the arrow icon that indicated if the region is open or not - pub fn paint_icon(&self, ui: &mut Ui, interact: &InteractInfo) { - let stroke_color = ui.style().interact(interact).stroke_color; - let stroke_width = ui.style().interact(interact).stroke_width; + pub fn paint_icon(&self, ui: &mut Ui, response: &Response) { + let stroke_color = ui.style().interact(response).stroke_color; + let stroke_width = ui.style().interact(response).stroke_width; - let rect = interact.rect; + let rect = response.rect; let openness = self.openness(ui); @@ -135,10 +135,10 @@ impl State { r })) } else if self.open { - let r_interact = ui.add_custom(add_contents); - let full_size = r_interact.1.size(); + let ret_rect = ui.add_custom(add_contents); + let full_size = ret_rect.1.size(); self.open_height = Some(full_size.y); - Some(r_interact) + Some(ret_rect) } else { None } @@ -211,27 +211,27 @@ impl CollapsingHeader { ); let rect = ui.allocate_space(size); - let interact = ui.interact(rect, id, Sense::click()); - let text_pos = pos2(text_pos.x, interact.rect.center().y - galley.size.y / 2.0); + let response = ui.interact(rect, id, Sense::click()); + let text_pos = pos2(text_pos.x, response.rect.center().y - galley.size.y / 2.0); let mut state = State::from_memory_with_default_open(ui.ctx(), id, default_open); - if interact.clicked { + if response.clicked { state.toggle(ui); } let bg_index = ui.painter().add(PaintCmd::Noop); { - let (mut icon_rect, _) = ui.style().icon_rectangles(interact.rect); + let (mut icon_rect, _) = ui.style().icon_rectangles(response.rect); icon_rect.set_center(pos2( - interact.rect.left() + ui.style().indent / 2.0, - interact.rect.center().y, + response.rect.left() + ui.style().indent / 2.0, + response.rect.center().y, )); - let icon_interact = InteractInfo { + let icon_response = Response { rect: icon_rect, - ..interact + ..response.clone() }; - state.paint_icon(ui, &icon_interact); + state.paint_icon(ui, &icon_response); } let painter = ui.painter(); @@ -239,16 +239,16 @@ impl CollapsingHeader { text_pos, galley, label.text_style, - ui.style().interact(&interact).stroke_color, + ui.style().interact(&response).stroke_color, ); painter.set( bg_index, PaintCmd::Rect { - corner_radius: ui.style().interact(&interact).corner_radius, - fill: ui.style().interact(&interact).bg_fill, + corner_radius: ui.style().interact(&response).corner_radius, + fill: ui.style().interact(&response).bg_fill, outline: None, - rect: interact.rect, + rect: response.rect, }, ); @@ -257,8 +257,8 @@ impl CollapsingHeader { pub fn show(self, ui: &mut Ui, add_contents: impl FnOnce(&mut Ui) -> R) -> Option { let Prepared { id, mut state } = self.begin(ui); - let r_interact = state.add_contents(ui, |ui| ui.indent(id, add_contents).0); - let ret = r_interact.map(|ri| ri.0); + let ret_response = state.add_contents(ui, |ui| ui.indent(id, add_contents).0); + let ret = ret_response.map(|ri| ri.0); ui.memory().collapsing_headers.insert(id, state); ret } diff --git a/egui/src/containers/popup.rs b/egui/src/containers/popup.rs index 9203b611..a5aa4392 100644 --- a/egui/src/containers/popup.rs +++ b/egui/src/containers/popup.rs @@ -18,7 +18,7 @@ pub fn show_popup( id: Id, window_pos: Pos2, add_contents: impl FnOnce(&mut Ui), -) -> InteractInfo { +) -> Response { use containers::*; Area::new(id) .order(Order::Foreground) diff --git a/egui/src/containers/resize.rs b/egui/src/containers/resize.rs index b3da44f5..7fda9824 100644 --- a/egui/src/containers/resize.rs +++ b/egui/src/containers/resize.rs @@ -119,7 +119,7 @@ impl Resize { struct Prepared { id: Id, state: State, - corner_interact: Option, + corner_response: Option, content_ui: Ui, } @@ -143,19 +143,19 @@ impl Resize { let position = ui.available().min; - let corner_interact = if self.resizable { + let corner_response = if self.resizable { // Resize-corner: let corner_size = Vec2::splat(ui.style().resize_corner_size); let corner_rect = Rect::from_min_size(position + state.desired_size - corner_size, corner_size); - let corner_interact = ui.interact(corner_rect, id.with("corner"), Sense::drag()); + let corner_response = ui.interact(corner_rect, id.with("corner"), Sense::drag()); - if corner_interact.active { + if corner_response.active { if let Some(mouse_pos) = ui.input().mouse.pos { - state.desired_size = mouse_pos - position + 0.5 * corner_interact.rect.size(); + state.desired_size = mouse_pos - position + 0.5 * corner_response.rect.size(); } } - Some(corner_interact) + Some(corner_response) } else { None }; @@ -188,7 +188,7 @@ impl Resize { Prepared { id, state, - corner_interact, + corner_response, content_ui, } } @@ -204,7 +204,7 @@ impl Resize { let Prepared { id, mut state, - corner_interact, + corner_response, content_ui, } = prepared; @@ -229,7 +229,7 @@ impl Resize { // ------------------------------ - if self.outline && corner_interact.is_some() { + if self.outline && corner_response.is_some() { let rect = Rect::from_min_size(content_ui.top_left(), state.desired_size); let rect = rect.expand(2.0); // breathing room for content ui.painter().add(paint::PaintCmd::Rect { @@ -240,10 +240,10 @@ impl Resize { }); } - if let Some(corner_interact) = corner_interact { - paint_resize_corner(ui, &corner_interact); + if let Some(corner_response) = corner_response { + paint_resize_corner(ui, &corner_response); - if corner_interact.hovered || corner_interact.active { + if corner_response.hovered || corner_response.active { ui.ctx().output().cursor_icon = CursorIcon::ResizeNwSe; } } @@ -267,10 +267,10 @@ impl Resize { use crate::paint::LineStyle; -pub fn paint_resize_corner(ui: &mut Ui, interact: &InteractInfo) { - let color = ui.style().interact(interact).stroke_color; - let width = ui.style().interact(interact).stroke_width; - paint_resize_corner_with_style(ui, &interact.rect, LineStyle::new(width, color)); +pub fn paint_resize_corner(ui: &mut Ui, response: &Response) { + let color = ui.style().interact(response).stroke_color; + let width = ui.style().interact(response).stroke_width; + paint_resize_corner_with_style(ui, &response.rect, LineStyle::new(width, color)); } pub fn paint_resize_corner_with_style(ui: &mut Ui, rect: &Rect, style: LineStyle) { diff --git a/egui/src/containers/scroll_area.rs b/egui/src/containers/scroll_area.rs index c041d231..81a03fe9 100644 --- a/egui/src/containers/scroll_area.rs +++ b/egui/src/containers/scroll_area.rs @@ -175,8 +175,8 @@ impl Prepared { if content_is_too_small { // Drag contents to scroll (for touch screens mostly): - let content_interact = ui.interact(inner_rect, id.with("area"), Sense::drag()); - if content_interact.active { + let content_response = ui.interact(inner_rect, id.with("area"), Sense::drag()); + if content_response.active { state.offset.y -= ui.input().mouse.delta.y; } } @@ -225,26 +225,26 @@ impl Prepared { // intentionally use same id for inside and outside of handle let interact_id = id.with("vertical"); - let mut interact = ui.interact(handle_rect, interact_id, Sense::click_and_drag()); + let mut response = ui.interact(handle_rect, interact_id, Sense::click_and_drag()); if let Some(mouse_pos) = ui.input().mouse.pos { - if interact.active { + if response.active { if inner_rect.top() <= mouse_pos.y && mouse_pos.y <= inner_rect.bottom() { state.offset.y += ui.input().mouse.delta.y * content_size.y / inner_rect.height(); } } else { // Check for mouse down outside handle: - let scroll_bg_interact = + let scroll_bg_response = ui.interact(outer_scroll_rect, interact_id, Sense::click_and_drag()); - if scroll_bg_interact.active { + if scroll_bg_response.active { // Center scroll at mouse pos: let mpos_top = mouse_pos.y - handle_rect.height() / 2.0; state.offset.y = remap(mpos_top, top..=bottom, 0.0..=content_size.y); } - interact = interact.union(scroll_bg_interact); + response = response.union(scroll_bg_response); } } @@ -265,8 +265,8 @@ impl Prepared { } let style = ui.style(); - let handle_fill = style.interact(&interact).fill; - let handle_outline = style.interact(&interact).rect_outline; + let handle_fill = style.interact(&response).fill; + let handle_outline = style.interact(&response).rect_outline; ui.painter().add(paint::PaintCmd::Rect { rect: outer_scroll_rect, diff --git a/egui/src/containers/window.rs b/egui/src/containers/window.rs index 9e88a1fc..ee4de8f1 100644 --- a/egui/src/containers/window.rs +++ b/egui/src/containers/window.rs @@ -156,11 +156,7 @@ impl<'open> Window<'open> { } impl<'open> Window<'open> { - pub fn show( - self, - ctx: &Arc, - add_contents: impl FnOnce(&mut Ui), - ) -> Option { + pub fn show(self, ctx: &Arc, add_contents: impl FnOnce(&mut Ui)) -> Option { self.show_impl(ctx, Box::new(add_contents)) } @@ -168,7 +164,7 @@ impl<'open> Window<'open> { self, ctx: &Arc, add_contents: Box, - ) -> Option { + ) -> Option { let Window { title_label, open, @@ -309,9 +305,9 @@ impl<'open> Window<'open> { ); } } - let full_interact = area.end(ctx, area_content_ui); + let full_response = area.end(ctx, area_content_ui); - Some(full_interact) + Some(full_response) } } @@ -603,11 +599,11 @@ fn show_title_bar( ui.allocate_space(vec2(0.0, 0.0)); // HACK: will add left spacing let rect = ui.allocate_space(Vec2::splat(button_size)); - let collapse_button_interact = ui.interact(rect, collapsing_id, Sense::click()); - if collapse_button_interact.clicked { + let collapse_button_response = ui.interact(rect, collapsing_id, Sense::click()); + if collapse_button_response.clicked { collapsing.toggle(ui); } - collapsing.paint_icon(ui, &collapse_button_interact); + collapsing.paint_icon(ui, &collapse_button_response); } let title_galley = title_label.layout(ui); @@ -688,7 +684,7 @@ impl TitleBar { } } - fn close_button_ui(&self, ui: &mut Ui) -> InteractInfo { + fn close_button_ui(&self, ui: &mut Ui) -> Response { let button_size = ui.style().start_icon_width; let button_rect = Rect::from_min_size( pos2( @@ -702,13 +698,13 @@ impl TitleBar { } } -fn close_button(ui: &mut Ui, rect: Rect) -> InteractInfo { +fn close_button(ui: &mut Ui, rect: Rect) -> Response { let close_id = ui.make_child_id("window_close_button"); - let interact = ui.interact(rect, close_id, Sense::click()); - ui.expand_to_include_child(interact.rect); + let response = ui.interact(rect, close_id, Sense::click()); + ui.expand_to_include_child(response.rect); - let stroke_color = ui.style().interact(&interact).stroke_color; - let stroke_width = ui.style().interact(&interact).stroke_width; + let stroke_color = ui.style().interact(&response).stroke_color; + let stroke_width = ui.style().interact(&response).stroke_width; ui.painter().line_segment( [rect.left_top(), rect.right_bottom()], (stroke_width, stroke_color), @@ -717,5 +713,5 @@ fn close_button(ui: &mut Ui, rect: Rect) -> InteractInfo { [rect.right_top(), rect.left_bottom()], (stroke_width, stroke_color), ); - interact + response } diff --git a/egui/src/context.rs b/egui/src/context.rs index 1f58fa89..ab520ccc 100644 --- a/egui/src/context.rs +++ b/egui/src/context.rs @@ -347,14 +347,15 @@ impl Context { } } - pub fn interact( - &self, + /// Use `ui.interact` instead + pub(crate) fn interact( + self: &Arc, layer: Layer, clip_rect: Rect, rect: Rect, interaction_id: Option, sense: Sense, - ) -> InteractInfo { + ) -> Response { let interact_rect = rect.expand2(0.5 * self.style().item_spacing); // make it easier to click. TODO: nice way to do this let hovered = self.contains_mouse(layer, clip_rect, interact_rect); let has_kb_focus = interaction_id @@ -363,7 +364,8 @@ impl Context { if interaction_id.is_none() || sense == Sense::nothing() { // Not interested in input: - return InteractInfo { + return Response { + ctx: self.clone(), sense, rect, hovered, @@ -385,7 +387,8 @@ impl Context { if self.input.mouse.pressed { if hovered { - let mut info = InteractInfo { + let mut response = Response { + ctx: self.clone(), sense, rect, hovered: true, @@ -398,7 +401,7 @@ impl Context { if sense.click && memory.interaction.click_id.is_none() { // start of a click memory.interaction.click_id = Some(interaction_id); - info.active = true; + response.active = true; } if sense.drag @@ -408,13 +411,14 @@ impl Context { memory.interaction.drag_id = Some(interaction_id); memory.interaction.drag_is_window = false; memory.window_interaction = None; // HACK: stop moving windows (if any) - info.active = true; + response.active = true; } - info + response } else { // miss - InteractInfo { + Response { + ctx: self.clone(), sense, rect, hovered, @@ -426,7 +430,8 @@ impl Context { } } else if self.input.mouse.released { let clicked = hovered && active && self.input.mouse.could_be_click; - InteractInfo { + Response { + ctx: self.clone(), sense, rect, hovered, @@ -436,7 +441,8 @@ impl Context { has_kb_focus, } } else if self.input.mouse.down { - InteractInfo { + Response { + ctx: self.clone(), sense, rect, hovered: hovered && active, @@ -446,7 +452,8 @@ impl Context { has_kb_focus, } } else { - InteractInfo { + Response { + ctx: self.clone(), sense, rect, hovered, diff --git a/egui/src/demos/app.rs b/egui/src/demos/app.rs index ade2c551..639b982d 100644 --- a/egui/src/demos/app.rs +++ b/egui/src/demos/app.rs @@ -625,8 +625,8 @@ impl Painting { fn content(&mut self, ui: &mut Ui) { let rect = ui.allocate_space(ui.available_finite().size()); - let interact = ui.interact(rect, ui.id(), Sense::drag()); - let rect = interact.rect; + let response = ui.interact(rect, ui.id(), Sense::drag()); + let rect = response.rect; let clip_rect = ui.clip_rect().intersect(rect); // Make sure we don't paint out of bounds let painter = Painter::new(ui.ctx().clone(), ui.layer(), clip_rect); @@ -636,7 +636,7 @@ impl Painting { let current_line = self.lines.last_mut().unwrap(); - if interact.active { + if response.active { if let Some(mouse_pos) = ui.input().mouse.pos { let canvas_pos = mouse_pos - rect.min; if current_line.last() != Some(&canvas_pos) { @@ -669,7 +669,7 @@ use crate::layout::*; #[cfg_attr(feature = "serde", serde(default))] struct LayoutDemo { dir: Direction, - align: Option, // None == jusitifed + align: Option, // None == justified reversed: bool, } @@ -735,7 +735,7 @@ impl LayoutDemo { } if ui .add(RadioButton::new(self.align == None, "Justified")) - .tooltip_text("Try to fill full width/heigth (e.g. buttons)") + .tooltip_text("Try to fill full width/height (e.g. buttons)") .clicked { self.align = None; diff --git a/egui/src/menu.rs b/egui/src/menu.rs index 79821059..1c495cf3 100644 --- a/egui/src/menu.rs +++ b/egui/src/menu.rs @@ -111,19 +111,19 @@ fn menu_impl<'c>( button = button.fill(Some(ui.style().interact.active.fill)); } - let button_interact = ui.add(button); + let button_response = ui.add(button); - interact_with_menu_button(&mut bar_state, ui.input(), menu_id, &button_interact); + interact_with_menu_button(&mut bar_state, ui.input(), menu_id, &button_response); if bar_state.open_menu == Some(menu_id) { let area = Area::new(menu_id) .order(Order::Foreground) - .fixed_pos(button_interact.rect.left_bottom()); + .fixed_pos(button_response.rect.left_bottom()); let frame = Frame::menu(ui.style()); let resize = Resize::default().auto_sized().outline(false); - let menu_interact = area.show(ui.ctx(), |ui| { + let menu_response = area.show(ui.ctx(), |ui| { frame.show(ui, |ui| { resize.show(ui, |ui| { let mut style = ui.style().clone(); @@ -141,7 +141,7 @@ fn menu_impl<'c>( }) }); - if menu_interact.hovered && ui.input().mouse.released { + if menu_response.hovered && ui.input().mouse.released { bar_state.open_menu = None; } } @@ -153,9 +153,9 @@ fn interact_with_menu_button( bar_state: &mut BarState, input: &InputState, menu_id: Id, - button_interact: &GuiResponse, + button_response: &Response, ) { - if button_interact.hovered && input.mouse.pressed { + if button_response.hovered && input.mouse.pressed { if bar_state.open_menu.is_some() { bar_state.open_menu = None; } else { @@ -164,7 +164,7 @@ fn interact_with_menu_button( } } - if button_interact.hovered && input.mouse.released && bar_state.open_menu.is_some() { + if button_response.hovered && input.mouse.released && bar_state.open_menu.is_some() { let time_since_open = input.time - bar_state.open_time; if time_since_open < 0.4 { // A quick click @@ -176,7 +176,7 @@ fn interact_with_menu_button( } } - if button_interact.hovered && bar_state.open_menu.is_some() { + if button_response.hovered && bar_state.open_menu.is_some() { bar_state.open_menu = Some(menu_id); } } diff --git a/egui/src/style.rs b/egui/src/style.rs index 6bfd05da..a521941e 100644 --- a/egui/src/style.rs +++ b/egui/src/style.rs @@ -152,12 +152,12 @@ impl Default for Interact { } impl Interact { - pub fn style(&self, interact: &InteractInfo) -> &WidgetStyle { - if interact.active || interact.has_kb_focus { + pub fn style(&self, response: &Response) -> &WidgetStyle { + if response.active || response.has_kb_focus { &self.active - } else if interact.sense == Sense::nothing() { + } else if response.sense == Sense::nothing() { &self.disabled - } else if interact.hovered { + } else if response.hovered { &self.hovered } else { &self.inactive @@ -216,9 +216,10 @@ impl Default for MenuBar { } impl Style { + // TODO: rename style.interact() to something better /// Use this style for interactive things - pub fn interact(&self, interact: &InteractInfo) -> &WidgetStyle { - self.interact.style(interact) + pub fn interact(&self, response: &Response) -> &WidgetStyle { + self.interact.style(response) } /// Returns small icon rectangle and big icon rectangle diff --git a/egui/src/types.rs b/egui/src/types.rs index 2c613d7b..80de6052 100644 --- a/egui/src/types.rs +++ b/egui/src/types.rs @@ -46,75 +46,16 @@ impl Default for CursorIcon { // ---------------------------------------------------------------------------- -/// The result of an interaction. -/// -/// For instance, this lets you know whether or not a widget has been clicked this frame. -#[derive(Clone, Copy, Debug)] -// #[cfg_attr(feature = "serde", derive(serde::Serialize))] -pub struct InteractInfo { - // IN: - /// The region of the screen we are talking about - pub rect: Rect, - - /// The senses (click or drag) that the widget is interested in (if any). - pub sense: Sense, - - // OUT: - /// The mouse is hovering above this thing - pub hovered: bool, - - /// The mouse pressed this thing earlier, and now released on this thing too. - pub clicked: bool, - - pub double_clicked: bool, - - /// The mouse is interacting with this thing (e.g. dragging it or holding it) - pub active: bool, - - /// This widget has the keyboard focus (i.e. is receiving key pressed) - pub has_kb_focus: bool, -} - -impl InteractInfo { - pub fn nothing() -> Self { - Self { - rect: Rect::nothing(), - sense: Sense::nothing(), - hovered: false, - clicked: false, - double_clicked: false, - active: false, - has_kb_focus: false, - } - } - - pub fn from_rect(rect: Rect) -> Self { - Self { - rect, - ..Self::nothing() - } - } - - pub fn union(self, other: Self) -> Self { - Self { - rect: self.rect.union(other.rect), - sense: self.sense.union(other.sense), - hovered: self.hovered || other.hovered, - clicked: self.clicked || other.clicked, - double_clicked: self.double_clicked || other.double_clicked, - active: self.active || other.active, - has_kb_focus: self.has_kb_focus || other.has_kb_focus, - } - } -} - -// ---------------------------------------------------------------------------- - /// The result of adding a widget to an `Ui`. /// /// This lets you know whether or not a widget has been clicked this frame. /// It also lets you easily show a tooltip on hover. -pub struct GuiResponse { +#[derive(Clone)] +pub struct Response { + // CONTEXT: + /// Used for optionally showing a tooltip + pub ctx: Arc, + // IN: /// The area of the screen we are talking about pub rect: Rect, @@ -129,6 +70,7 @@ pub struct GuiResponse { /// The mouse clicked this thing this frame pub clicked: bool, + /// The thing was double-clicked pub double_clicked: bool, /// The mouse is interacting with this thing (e.g. dragging it) @@ -136,13 +78,9 @@ pub struct GuiResponse { /// This widget has the keyboard focus (i.e. is receiving key pressed) pub has_kb_focus: bool, - - // CONTEXT: - /// Used for optionally showing a tooltip - pub ctx: Arc, } -impl GuiResponse { +impl Response { /// Show some stuff if the item was hovered pub fn tooltip(&mut self, add_contents: impl FnOnce(&mut Ui)) -> &mut Self { if self.hovered { @@ -159,16 +97,18 @@ impl GuiResponse { } } -impl Into for GuiResponse { - fn into(self) -> InteractInfo { - InteractInfo { - rect: self.rect, - sense: self.sense, - hovered: self.hovered, - clicked: self.clicked, - double_clicked: self.double_clicked, - active: self.active, - has_kb_focus: self.has_kb_focus, +impl Response { + pub fn union(self, other: Self) -> Self { + assert!(Arc::ptr_eq(&self.ctx, &other.ctx)); + Self { + ctx: self.ctx, + rect: self.rect.union(other.rect), + sense: self.sense.union(other.sense), + hovered: self.hovered || other.hovered, + clicked: self.clicked || other.clicked, + double_clicked: self.double_clicked || other.double_clicked, + active: self.active || other.active, + has_kb_focus: self.has_kb_focus || other.has_kb_focus, } } } diff --git a/egui/src/ui.rs b/egui/src/ui.rs index c37aa6ad..a80a040b 100644 --- a/egui/src/ui.rs +++ b/egui/src/ui.rs @@ -327,12 +327,12 @@ impl Ui { /// # Interaction impl Ui { - pub fn interact(&self, rect: Rect, id: Id, sense: Sense) -> InteractInfo { + pub fn interact(&self, rect: Rect, id: Id, sense: Sense) -> Response { self.ctx() .interact(self.layer(), self.clip_rect(), rect, Some(id), sense) } - pub fn interact_hover(&self, rect: Rect) -> InteractInfo { + pub fn interact_hover(&self, rect: Rect) -> Response { self.ctx() .interact(self.layer(), self.clip_rect(), rect, None, Sense::nothing()) } @@ -341,30 +341,6 @@ impl Ui { self.interact_hover(rect).hovered } - #[must_use] - pub fn response(&mut self, interact: InteractInfo) -> GuiResponse { - // TODO: unify GuiResponse and InteractInfo. They are the same thing! - let InteractInfo { - sense, - hovered, - clicked, - double_clicked, - active, - has_kb_focus, - rect, - } = interact; - GuiResponse { - sense, - hovered, - clicked, - double_clicked, - active, - has_kb_focus, - rect, - ctx: self.ctx().clone(), - } - } - // ------------------------------------------------------------------------ // Stuff that moves the cursor, i.e. allocates space in this ui! @@ -429,44 +405,43 @@ impl Ui { /// # Adding widgets impl Ui { - pub fn add(&mut self, widget: impl Widget) -> GuiResponse { - let interact = widget.ui(self); - self.response(interact) + pub fn add(&mut self, widget: impl Widget) -> Response { + widget.ui(self) } /// Shortcut for `add(Label::new(text))` - pub fn label(&mut self, label: impl Into