Skip to content

Commit

Permalink
Only one Interaction member of Memory
Browse files Browse the repository at this point in the history
  • Loading branch information
emilk committed Nov 7, 2023
1 parent 72d77bc commit 1a261ed
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 61 deletions.
4 changes: 2 additions & 2 deletions crates/egui/src/containers/panel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -702,9 +702,9 @@ impl TopBottomPanel {
if ui.input(|i| i.pointer.any_pressed() && i.pointer.any_down())
&& mouse_over_resize_line
{
ui.memory_mut(|mem| mem.interaction.drag_id = Some(resize_id));
ui.memory_mut(|mem| mem.interaction_mut().drag_id = Some(resize_id));
}
is_resizing = ui.memory(|mem| mem.interaction.drag_id == Some(resize_id));
is_resizing = ui.memory(|mem| mem.interaction().drag_id == Some(resize_id));
if is_resizing {
let height = (pointer.y - side.side_y(panel_rect)).abs();
let height =
Expand Down
10 changes: 5 additions & 5 deletions crates/egui/src/containers/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -633,7 +633,7 @@ fn window_interaction(
rect: Rect,
) -> Option<WindowInteraction> {
{
let drag_id = ctx.memory(|mem| mem.interaction.drag_id);
let drag_id = ctx.memory(|mem| mem.interaction().drag_id);

if drag_id.is_some() && drag_id != Some(id) {
return None;
Expand All @@ -647,8 +647,8 @@ fn window_interaction(
hover_window_interaction.set_cursor(ctx);
if ctx.input(|i| i.pointer.any_pressed() && i.pointer.primary_down()) {
ctx.memory_mut(|mem| {
mem.interaction.drag_id = Some(id);
mem.interaction.drag_is_window = true;
mem.interaction_mut().drag_id = Some(id);
mem.interaction_mut().drag_is_window = true;
window_interaction = Some(hover_window_interaction);
mem.set_window_interaction(window_interaction);
});
Expand All @@ -657,7 +657,7 @@ fn window_interaction(
}

if let Some(window_interaction) = window_interaction {
let is_active = ctx.memory_mut(|mem| mem.interaction.drag_id == Some(id));
let is_active = ctx.memory_mut(|mem| mem.interaction().drag_id == Some(id));

if is_active && window_interaction.area_layer_id == area_layer_id {
return Some(window_interaction);
Expand Down Expand Up @@ -685,7 +685,7 @@ fn resize_hover(
}
}

if ctx.memory(|mem| mem.interaction.drag_interest) {
if ctx.memory(|mem| mem.interaction().drag_interest) {
// Another widget will become active if we drag here
return None;
}
Expand Down
40 changes: 18 additions & 22 deletions crates/egui/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,13 +191,6 @@ struct ContextImpl {

impl ContextImpl {
fn begin_frame_mut(&mut self, mut new_raw_input: RawInput, id_pair: ViewportIdPair) {
if let Some(id_pair) = self.viewport_stack.last().copied() {
let previous_viewport_id = id_pair.this;

// Pause the active viewport
self.memory.pause_frame(previous_viewport_id);
}

let viewport_id = id_pair.this;
self.viewport_stack.push(id_pair);
self.output.entry(self.viewport_id()).or_default();
Expand Down Expand Up @@ -915,21 +908,25 @@ impl Context {
}

if sense.click || sense.drag {
memory.interaction.click_interest |= hovered && sense.click;
memory.interaction.drag_interest |= hovered && sense.drag;
let interaction = memory.interaction_mut();

response.dragged = memory.interaction.drag_id == Some(id);
interaction.click_interest |= hovered && sense.click;
interaction.drag_interest |= hovered && sense.drag;

response.dragged = interaction.drag_id == Some(id);
response.is_pointer_button_down_on =
memory.interaction.click_id == Some(id) || response.dragged;
interaction.click_id == Some(id) || response.dragged;

for pointer_event in &input.pointer.pointer_events {
match pointer_event {
PointerEvent::Moved(_) => {}
PointerEvent::Pressed { .. } => {
if hovered {
if sense.click && memory.interaction.click_id.is_none() {
let interaction = memory.interaction_mut();

if sense.click && interaction.click_id.is_none() {
// potential start of a click
memory.interaction.click_id = Some(id);
interaction.click_id = Some(id);
response.is_pointer_button_down_on = true;
}

Expand All @@ -939,12 +936,11 @@ impl Context {
// This is needed because we do window interaction first (to prevent frame delay),
// and then do content layout.
if sense.drag
&& (memory.interaction.drag_id.is_none()
|| memory.interaction.drag_is_window)
&& (interaction.drag_id.is_none() || interaction.drag_is_window)
{
// potential start of a drag
memory.interaction.drag_id = Some(id);
memory.interaction.drag_is_window = false;
interaction.drag_id = Some(id);
interaction.drag_is_window = false;
memory.set_window_interaction(None); // HACK: stop moving windows (if any)
response.is_pointer_button_down_on = true;
response.dragged = true;
Expand Down Expand Up @@ -1598,7 +1594,7 @@ impl Context {
} else {
let viewport_id = self.viewport_id();
self.write(|ctx| {
ctx.memory.resume_frame(viewport_id);
ctx.memory.set_viewport_id(viewport_id);
});
}

Expand Down Expand Up @@ -1751,12 +1747,12 @@ impl Context {
///
/// NOTE: this will return `false` if the pointer is just hovering over an egui area.
pub fn is_using_pointer(&self) -> bool {
self.memory(|m| m.interaction.is_using_pointer())
self.memory(|m| m.interaction().is_using_pointer())
}

/// If `true`, egui is currently listening on text input (e.g. typing text in a [`TextEdit`]).
pub fn wants_keyboard_input(&self) -> bool {
self.memory(|m| m.interaction.focus.focused().is_some())
self.memory(|m| m.interaction().focus.focused().is_some())
}

/// Highlight this widget, to make it look like it is hovered, even if it isn't.
Expand Down Expand Up @@ -1960,7 +1956,7 @@ impl Context {
.on_hover_text("Is egui currently listening for text input?");
ui.label(format!(
"Keyboard focus widget: {}",
self.memory(|m| m.interaction.focus.focused())
self.memory(|m| m.interaction().focus.focused())
.as_ref()
.map(Id::short_debug_format)
.unwrap_or_default()
Expand Down Expand Up @@ -2167,7 +2163,7 @@ impl Context {
ui.label("NOTE: the position of this window cannot be reset from within itself.");

ui.collapsing("Interaction", |ui| {
let interaction = self.memory(|mem| mem.interaction.clone());
let interaction = self.memory(|mem| mem.interaction().clone());
interaction.ui(ui);
});
}
Expand Down
62 changes: 30 additions & 32 deletions crates/egui/src/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,6 @@ pub struct Memory {
#[cfg_attr(feature = "persistence", serde(skip))]
pub(crate) new_font_definitions: Option<epaint::text::FontDefinitions>,

#[cfg_attr(feature = "persistence", serde(skip))]
pub(crate) interactions: ViewportIdMap<Interaction>,

#[cfg_attr(feature = "persistence", serde(skip))]
pub(crate) interaction: Interaction,

// Current viewport
#[cfg_attr(feature = "persistence", serde(skip))]
pub(crate) viewport_id: ViewportId,
Expand All @@ -100,11 +94,13 @@ pub struct Memory {
everything_is_visible: bool,

// -------------------------------------------------

// Per-viewport:
#[cfg_attr(feature = "persistence", serde(skip))]
areas: ViewportIdMap<Areas>,

#[cfg_attr(feature = "persistence", serde(skip))]
pub(crate) interactions: ViewportIdMap<Interaction>,

#[cfg_attr(feature = "persistence", serde(skip))]
window_interactions: ViewportIdMap<window::WindowInteraction>,
}
Expand All @@ -118,14 +114,14 @@ impl Default for Memory {
override_pixels_per_point: Default::default(),
new_font_definitions: Default::default(),
interactions: Default::default(),
interaction: Default::default(),
viewport_id: Default::default(),
window_interactions: Default::default(),
drag_value: Default::default(),
areas: Default::default(),
popup: Default::default(),
everything_is_visible: Default::default(),
};
slf.interactions.entry(slf.viewport_id).or_default();
slf.areas.entry(slf.viewport_id).or_default();
slf
}
Expand Down Expand Up @@ -555,19 +551,13 @@ impl Memory {
.entry(viewport_id)
.or_default()
.begin_frame(prev_input, new_input);
self.interaction = self.interactions.remove(&viewport_id).unwrap();
self.areas.entry(viewport_id).or_default();

if !prev_input.pointer.any_down() {
self.window_interactions.remove(&viewport_id);
}
}

pub(crate) fn pause_frame(&mut self, viewport_id: ViewportId) {
self.interactions
.insert(viewport_id, std::mem::take(&mut self.interaction));
}

pub(crate) fn end_frame(
&mut self,
input: &InputState,
Expand All @@ -576,18 +566,15 @@ impl Memory {
) {
self.caches.update();
self.areas_mut().end_frame();
self.interaction.focus.end_frame(used_ids);
self.interactions
.insert(self.viewport_id, std::mem::take(&mut self.interaction));
self.interaction_mut().focus.end_frame(used_ids);
self.drag_value.end_frame(input);
self.interactions.retain(|id, _| viewports.contains(id));
self.areas.retain(|id, _| viewports.contains(id));
self.window_interactions
.retain(|id, _| viewports.contains(id));
}

pub(crate) fn resume_frame(&mut self, viewport_id: ViewportId) {
self.interaction = self.interactions.remove(&viewport_id).unwrap_or_default();
pub(crate) fn set_viewport_id(&mut self, viewport_id: ViewportId) {
self.viewport_id = viewport_id;
}

Expand All @@ -614,7 +601,7 @@ impl Memory {
}

pub(crate) fn had_focus_last_frame(&self, id: Id) -> bool {
self.interaction.focus.id_previous_frame == Some(id)
self.interaction().focus.id_previous_frame == Some(id)
}

/// True if the given widget had keyboard focus last frame, but not this one.
Expand All @@ -635,12 +622,12 @@ impl Memory {
/// from the window and back.
#[inline(always)]
pub fn has_focus(&self, id: Id) -> bool {
self.interaction.focus.focused() == Some(id)
self.interaction().focus.focused() == Some(id)
}

/// Which widget has keyboard focus?
pub fn focus(&self) -> Option<Id> {
self.interaction.focus.focused()
self.interaction().focus.focused()
}

/// Set an event filter for a widget.
Expand All @@ -651,7 +638,7 @@ impl Memory {
/// You must first give focus to the widget before calling this.
pub fn set_focus_lock_filter(&mut self, id: Id, event_filter: EventFilter) {
if self.had_focus_last_frame(id) && self.has_focus(id) {
if let Some(focused) = &mut self.interaction.focus.focused_widget {
if let Some(focused) = &mut self.interaction_mut().focus.focused_widget {
if focused.id == id {
focused.filter = event_filter;
}
Expand All @@ -678,15 +665,16 @@ impl Memory {
/// See also [`crate::Response::request_focus`].
#[inline(always)]
pub fn request_focus(&mut self, id: Id) {
self.interaction.focus.focused_widget = Some(FocusWidget::new(id));
self.interaction_mut().focus.focused_widget = Some(FocusWidget::new(id));
}

/// Surrender keyboard focus for a specific widget.
/// See also [`crate::Response::surrender_focus`].
#[inline(always)]
pub fn surrender_focus(&mut self, id: Id) {
if self.interaction.focus.focused() == Some(id) {
self.interaction.focus.focused_widget = None;
let interaction = self.interaction_mut();
if interaction.focus.focused() == Some(id) {
interaction.focus.focused_widget = None;
}
}

Expand All @@ -699,37 +687,37 @@ impl Memory {
/// and rendered correctly in a single frame.
#[inline(always)]
pub fn interested_in_focus(&mut self, id: Id) {
self.interaction.focus.interested_in_focus(id);
self.interaction_mut().focus.interested_in_focus(id);
}

/// Stop editing of active [`TextEdit`](crate::TextEdit) (if any).
#[inline(always)]
pub fn stop_text_input(&mut self) {
self.interaction.focus.focused_widget = None;
self.interaction_mut().focus.focused_widget = None;
}

/// Is any widget being dragged?
#[inline(always)]
pub fn is_anything_being_dragged(&self) -> bool {
self.interaction.drag_id.is_some()
self.interaction().drag_id.is_some()
}

/// Is this specific widget being dragged?
#[inline(always)]
pub fn is_being_dragged(&self, id: Id) -> bool {
self.interaction.drag_id == Some(id)
self.interaction().drag_id == Some(id)
}

/// Set which widget is being dragged.
#[inline(always)]
pub fn set_dragged_id(&mut self, id: Id) {
self.interaction.drag_id = Some(id);
self.interaction_mut().drag_id = Some(id);
}

/// Stop dragging any widget.
#[inline(always)]
pub fn stop_dragging(&mut self) {
self.interaction.drag_id = None;
self.interaction_mut().drag_id = None;
}

/// Forget window positions, sizes etc.
Expand All @@ -754,6 +742,16 @@ impl Memory {
self.window_interactions.remove(&self.viewport_id);
}
}

pub(crate) fn interaction(&self) -> &Interaction {
self.interactions
.get(&self.viewport_id)
.expect("Failed to get interaction")
}

pub(crate) fn interaction_mut(&mut self) -> &mut Interaction {
self.interactions.entry(self.viewport_id).or_default()
}
}

/// ## Popups
Expand Down

0 comments on commit 1a261ed

Please sign in to comment.