mirror of
https://github.com/emilk/egui.git
synced 2026-09-02 06:40:06 -04:00
Only one Interaction member of Memory
This commit is contained in:
@@ -702,9 +702,9 @@ impl TopBottomPanel {
|
|||||||
if ui.input(|i| i.pointer.any_pressed() && i.pointer.any_down())
|
if ui.input(|i| i.pointer.any_pressed() && i.pointer.any_down())
|
||||||
&& mouse_over_resize_line
|
&& 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 {
|
if is_resizing {
|
||||||
let height = (pointer.y - side.side_y(panel_rect)).abs();
|
let height = (pointer.y - side.side_y(panel_rect)).abs();
|
||||||
let height =
|
let height =
|
||||||
|
|||||||
@@ -633,7 +633,7 @@ fn window_interaction(
|
|||||||
rect: Rect,
|
rect: Rect,
|
||||||
) -> Option<WindowInteraction> {
|
) -> 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) {
|
if drag_id.is_some() && drag_id != Some(id) {
|
||||||
return None;
|
return None;
|
||||||
@@ -647,8 +647,8 @@ fn window_interaction(
|
|||||||
hover_window_interaction.set_cursor(ctx);
|
hover_window_interaction.set_cursor(ctx);
|
||||||
if ctx.input(|i| i.pointer.any_pressed() && i.pointer.primary_down()) {
|
if ctx.input(|i| i.pointer.any_pressed() && i.pointer.primary_down()) {
|
||||||
ctx.memory_mut(|mem| {
|
ctx.memory_mut(|mem| {
|
||||||
mem.interaction.drag_id = Some(id);
|
mem.interaction_mut().drag_id = Some(id);
|
||||||
mem.interaction.drag_is_window = true;
|
mem.interaction_mut().drag_is_window = true;
|
||||||
window_interaction = Some(hover_window_interaction);
|
window_interaction = Some(hover_window_interaction);
|
||||||
mem.set_window_interaction(window_interaction);
|
mem.set_window_interaction(window_interaction);
|
||||||
});
|
});
|
||||||
@@ -657,7 +657,7 @@ fn window_interaction(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(window_interaction) = 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 {
|
if is_active && window_interaction.area_layer_id == area_layer_id {
|
||||||
return Some(window_interaction);
|
return Some(window_interaction);
|
||||||
@@ -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
|
// Another widget will become active if we drag here
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -191,13 +191,6 @@ struct ContextImpl {
|
|||||||
|
|
||||||
impl ContextImpl {
|
impl ContextImpl {
|
||||||
fn begin_frame_mut(&mut self, mut new_raw_input: RawInput, id_pair: ViewportIdPair) {
|
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;
|
let viewport_id = id_pair.this;
|
||||||
self.viewport_stack.push(id_pair);
|
self.viewport_stack.push(id_pair);
|
||||||
self.output.entry(self.viewport_id()).or_default();
|
self.output.entry(self.viewport_id()).or_default();
|
||||||
@@ -915,21 +908,25 @@ impl Context {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if sense.click || sense.drag {
|
if sense.click || sense.drag {
|
||||||
memory.interaction.click_interest |= hovered && sense.click;
|
let interaction = memory.interaction_mut();
|
||||||
memory.interaction.drag_interest |= hovered && sense.drag;
|
|
||||||
|
|
||||||
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 =
|
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 {
|
for pointer_event in &input.pointer.pointer_events {
|
||||||
match pointer_event {
|
match pointer_event {
|
||||||
PointerEvent::Moved(_) => {}
|
PointerEvent::Moved(_) => {}
|
||||||
PointerEvent::Pressed { .. } => {
|
PointerEvent::Pressed { .. } => {
|
||||||
if hovered {
|
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
|
// potential start of a click
|
||||||
memory.interaction.click_id = Some(id);
|
interaction.click_id = Some(id);
|
||||||
response.is_pointer_button_down_on = true;
|
response.is_pointer_button_down_on = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -939,12 +936,11 @@ impl Context {
|
|||||||
// This is needed because we do window interaction first (to prevent frame delay),
|
// This is needed because we do window interaction first (to prevent frame delay),
|
||||||
// and then do content layout.
|
// and then do content layout.
|
||||||
if sense.drag
|
if sense.drag
|
||||||
&& (memory.interaction.drag_id.is_none()
|
&& (interaction.drag_id.is_none() || interaction.drag_is_window)
|
||||||
|| memory.interaction.drag_is_window)
|
|
||||||
{
|
{
|
||||||
// potential start of a drag
|
// potential start of a drag
|
||||||
memory.interaction.drag_id = Some(id);
|
interaction.drag_id = Some(id);
|
||||||
memory.interaction.drag_is_window = false;
|
interaction.drag_is_window = false;
|
||||||
memory.set_window_interaction(None); // HACK: stop moving windows (if any)
|
memory.set_window_interaction(None); // HACK: stop moving windows (if any)
|
||||||
response.is_pointer_button_down_on = true;
|
response.is_pointer_button_down_on = true;
|
||||||
response.dragged = true;
|
response.dragged = true;
|
||||||
@@ -1598,7 +1594,7 @@ impl Context {
|
|||||||
} else {
|
} else {
|
||||||
let viewport_id = self.viewport_id();
|
let viewport_id = self.viewport_id();
|
||||||
self.write(|ctx| {
|
self.write(|ctx| {
|
||||||
ctx.memory.resume_frame(viewport_id);
|
ctx.memory.set_viewport_id(viewport_id);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1751,12 +1747,12 @@ impl Context {
|
|||||||
///
|
///
|
||||||
/// NOTE: this will return `false` if the pointer is just hovering over an egui area.
|
/// NOTE: this will return `false` if the pointer is just hovering over an egui area.
|
||||||
pub fn is_using_pointer(&self) -> bool {
|
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`]).
|
/// If `true`, egui is currently listening on text input (e.g. typing text in a [`TextEdit`]).
|
||||||
pub fn wants_keyboard_input(&self) -> bool {
|
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.
|
/// Highlight this widget, to make it look like it is hovered, even if it isn't.
|
||||||
@@ -1960,7 +1956,7 @@ impl Context {
|
|||||||
.on_hover_text("Is egui currently listening for text input?");
|
.on_hover_text("Is egui currently listening for text input?");
|
||||||
ui.label(format!(
|
ui.label(format!(
|
||||||
"Keyboard focus widget: {}",
|
"Keyboard focus widget: {}",
|
||||||
self.memory(|m| m.interaction.focus.focused())
|
self.memory(|m| m.interaction().focus.focused())
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(Id::short_debug_format)
|
.map(Id::short_debug_format)
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
@@ -2167,7 +2163,7 @@ impl Context {
|
|||||||
ui.label("NOTE: the position of this window cannot be reset from within itself.");
|
ui.label("NOTE: the position of this window cannot be reset from within itself.");
|
||||||
|
|
||||||
ui.collapsing("Interaction", |ui| {
|
ui.collapsing("Interaction", |ui| {
|
||||||
let interaction = self.memory(|mem| mem.interaction.clone());
|
let interaction = self.memory(|mem| mem.interaction().clone());
|
||||||
interaction.ui(ui);
|
interaction.ui(ui);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,12 +78,6 @@ pub struct Memory {
|
|||||||
#[cfg_attr(feature = "persistence", serde(skip))]
|
#[cfg_attr(feature = "persistence", serde(skip))]
|
||||||
pub(crate) new_font_definitions: Option<epaint::text::FontDefinitions>,
|
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
|
// Current viewport
|
||||||
#[cfg_attr(feature = "persistence", serde(skip))]
|
#[cfg_attr(feature = "persistence", serde(skip))]
|
||||||
pub(crate) viewport_id: ViewportId,
|
pub(crate) viewport_id: ViewportId,
|
||||||
@@ -100,11 +94,13 @@ pub struct Memory {
|
|||||||
everything_is_visible: bool,
|
everything_is_visible: bool,
|
||||||
|
|
||||||
// -------------------------------------------------
|
// -------------------------------------------------
|
||||||
|
|
||||||
// Per-viewport:
|
// Per-viewport:
|
||||||
#[cfg_attr(feature = "persistence", serde(skip))]
|
#[cfg_attr(feature = "persistence", serde(skip))]
|
||||||
areas: ViewportIdMap<Areas>,
|
areas: ViewportIdMap<Areas>,
|
||||||
|
|
||||||
|
#[cfg_attr(feature = "persistence", serde(skip))]
|
||||||
|
pub(crate) interactions: ViewportIdMap<Interaction>,
|
||||||
|
|
||||||
#[cfg_attr(feature = "persistence", serde(skip))]
|
#[cfg_attr(feature = "persistence", serde(skip))]
|
||||||
window_interactions: ViewportIdMap<window::WindowInteraction>,
|
window_interactions: ViewportIdMap<window::WindowInteraction>,
|
||||||
}
|
}
|
||||||
@@ -118,7 +114,6 @@ impl Default for Memory {
|
|||||||
override_pixels_per_point: Default::default(),
|
override_pixels_per_point: Default::default(),
|
||||||
new_font_definitions: Default::default(),
|
new_font_definitions: Default::default(),
|
||||||
interactions: Default::default(),
|
interactions: Default::default(),
|
||||||
interaction: Default::default(),
|
|
||||||
viewport_id: Default::default(),
|
viewport_id: Default::default(),
|
||||||
window_interactions: Default::default(),
|
window_interactions: Default::default(),
|
||||||
drag_value: Default::default(),
|
drag_value: Default::default(),
|
||||||
@@ -126,6 +121,7 @@ impl Default for Memory {
|
|||||||
popup: Default::default(),
|
popup: Default::default(),
|
||||||
everything_is_visible: Default::default(),
|
everything_is_visible: Default::default(),
|
||||||
};
|
};
|
||||||
|
slf.interactions.entry(slf.viewport_id).or_default();
|
||||||
slf.areas.entry(slf.viewport_id).or_default();
|
slf.areas.entry(slf.viewport_id).or_default();
|
||||||
slf
|
slf
|
||||||
}
|
}
|
||||||
@@ -555,7 +551,6 @@ impl Memory {
|
|||||||
.entry(viewport_id)
|
.entry(viewport_id)
|
||||||
.or_default()
|
.or_default()
|
||||||
.begin_frame(prev_input, new_input);
|
.begin_frame(prev_input, new_input);
|
||||||
self.interaction = self.interactions.remove(&viewport_id).unwrap();
|
|
||||||
self.areas.entry(viewport_id).or_default();
|
self.areas.entry(viewport_id).or_default();
|
||||||
|
|
||||||
if !prev_input.pointer.any_down() {
|
if !prev_input.pointer.any_down() {
|
||||||
@@ -563,11 +558,6 @@ impl Memory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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(
|
pub(crate) fn end_frame(
|
||||||
&mut self,
|
&mut self,
|
||||||
input: &InputState,
|
input: &InputState,
|
||||||
@@ -576,9 +566,7 @@ impl Memory {
|
|||||||
) {
|
) {
|
||||||
self.caches.update();
|
self.caches.update();
|
||||||
self.areas_mut().end_frame();
|
self.areas_mut().end_frame();
|
||||||
self.interaction.focus.end_frame(used_ids);
|
self.interaction_mut().focus.end_frame(used_ids);
|
||||||
self.interactions
|
|
||||||
.insert(self.viewport_id, std::mem::take(&mut self.interaction));
|
|
||||||
self.drag_value.end_frame(input);
|
self.drag_value.end_frame(input);
|
||||||
self.interactions.retain(|id, _| viewports.contains(id));
|
self.interactions.retain(|id, _| viewports.contains(id));
|
||||||
self.areas.retain(|id, _| viewports.contains(id));
|
self.areas.retain(|id, _| viewports.contains(id));
|
||||||
@@ -586,8 +574,7 @@ impl Memory {
|
|||||||
.retain(|id, _| viewports.contains(id));
|
.retain(|id, _| viewports.contains(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn resume_frame(&mut self, viewport_id: ViewportId) {
|
pub(crate) fn set_viewport_id(&mut self, viewport_id: ViewportId) {
|
||||||
self.interaction = self.interactions.remove(&viewport_id).unwrap_or_default();
|
|
||||||
self.viewport_id = viewport_id;
|
self.viewport_id = viewport_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -614,7 +601,7 @@ impl Memory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn had_focus_last_frame(&self, id: Id) -> bool {
|
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.
|
/// True if the given widget had keyboard focus last frame, but not this one.
|
||||||
@@ -635,12 +622,12 @@ impl Memory {
|
|||||||
/// from the window and back.
|
/// from the window and back.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn has_focus(&self, id: Id) -> bool {
|
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?
|
/// Which widget has keyboard focus?
|
||||||
pub fn focus(&self) -> Option<Id> {
|
pub fn focus(&self) -> Option<Id> {
|
||||||
self.interaction.focus.focused()
|
self.interaction().focus.focused()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set an event filter for a widget.
|
/// Set an event filter for a widget.
|
||||||
@@ -651,7 +638,7 @@ impl Memory {
|
|||||||
/// You must first give focus to the widget before calling this.
|
/// You must first give focus to the widget before calling this.
|
||||||
pub fn set_focus_lock_filter(&mut self, id: Id, event_filter: EventFilter) {
|
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 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 {
|
if focused.id == id {
|
||||||
focused.filter = event_filter;
|
focused.filter = event_filter;
|
||||||
}
|
}
|
||||||
@@ -678,15 +665,16 @@ impl Memory {
|
|||||||
/// See also [`crate::Response::request_focus`].
|
/// See also [`crate::Response::request_focus`].
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn request_focus(&mut self, id: Id) {
|
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.
|
/// Surrender keyboard focus for a specific widget.
|
||||||
/// See also [`crate::Response::surrender_focus`].
|
/// See also [`crate::Response::surrender_focus`].
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn surrender_focus(&mut self, id: Id) {
|
pub fn surrender_focus(&mut self, id: Id) {
|
||||||
if self.interaction.focus.focused() == Some(id) {
|
let interaction = self.interaction_mut();
|
||||||
self.interaction.focus.focused_widget = None;
|
if interaction.focus.focused() == Some(id) {
|
||||||
|
interaction.focus.focused_widget = None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -699,37 +687,37 @@ impl Memory {
|
|||||||
/// and rendered correctly in a single frame.
|
/// and rendered correctly in a single frame.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn interested_in_focus(&mut self, id: Id) {
|
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).
|
/// Stop editing of active [`TextEdit`](crate::TextEdit) (if any).
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn stop_text_input(&mut self) {
|
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?
|
/// Is any widget being dragged?
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn is_anything_being_dragged(&self) -> bool {
|
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?
|
/// Is this specific widget being dragged?
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn is_being_dragged(&self, id: Id) -> bool {
|
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.
|
/// Set which widget is being dragged.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn set_dragged_id(&mut self, id: Id) {
|
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.
|
/// Stop dragging any widget.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn stop_dragging(&mut self) {
|
pub fn stop_dragging(&mut self) {
|
||||||
self.interaction.drag_id = None;
|
self.interaction_mut().drag_id = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Forget window positions, sizes etc.
|
/// Forget window positions, sizes etc.
|
||||||
@@ -754,6 +742,16 @@ impl Memory {
|
|||||||
self.window_interactions.remove(&self.viewport_id);
|
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
|
/// ## Popups
|
||||||
|
|||||||
Reference in New Issue
Block a user