implement for interact

This commit is contained in:
charburgx 2022-12-19 03:57:03 -06:00
parent 26c3fa22cb
commit d0307417e1
5 changed files with 45 additions and 16 deletions

View file

@ -2,7 +2,7 @@
//! It has no frame or own size. It is potentially movable. //! It has no frame or own size. It is potentially movable.
//! It is the foundation for windows and popups. //! It is the foundation for windows and popups.
use crate::*; use crate::{layers::ZLayer, *};
/// State that is persisted between frames. /// State that is persisted between frames.
// TODO(emilk): this is not currently stored in `memory().data`, but maybe it should be? // TODO(emilk): this is not currently stored in `memory().data`, but maybe it should be?
@ -268,7 +268,7 @@ impl Area {
let move_response = ctx.interact( let move_response = ctx.interact(
Rect::EVERYTHING, Rect::EVERYTHING,
ctx.style().spacing.item_spacing, ctx.style().spacing.item_spacing,
layer_id, ZLayer::from_area_layer(layer_id),
interact_id, interact_id,
state.rect(), state.rect(),
sense, sense,

View file

@ -2,9 +2,15 @@
use std::sync::Arc; use std::sync::Arc;
use crate::{ use crate::{
animation_manager::AnimationManager, data::output::PlatformOutput, frame_state::FrameState, animation_manager::AnimationManager,
input_state::*, layers::GraphicLayers, memory::Options, os::OperatingSystem, data::output::PlatformOutput,
output::FullOutput, TextureHandle, *, frame_state::FrameState,
input_state::*,
layers::{GraphicLayers, ZLayer, ZOrder},
memory::Options,
os::OperatingSystem,
output::FullOutput,
TextureHandle, *,
}; };
use epaint::{mutex::*, stats::*, text::Fonts, TessellationOptions, *}; use epaint::{mutex::*, stats::*, text::Fonts, TessellationOptions, *};
@ -64,9 +70,9 @@ struct ContextImpl {
requested_repaint_last_frame: bool, requested_repaint_last_frame: bool,
/// Written to during the frame. /// Written to during the frame.
layer_rects_this_frame: ahash::HashMap<AreaLayerId, Vec<(Id, Rect)>>, layer_rects_this_frame: ahash::HashMap<AreaLayerId, Vec<(Id, ZOrder, Rect)>>,
/// Read /// Read
layer_rects_prev_frame: ahash::HashMap<AreaLayerId, Vec<(Id, Rect)>>, layer_rects_prev_frame: ahash::HashMap<AreaLayerId, Vec<(Id, ZOrder, Rect)>>,
#[cfg(feature = "accesskit")] #[cfg(feature = "accesskit")]
is_accesskit_enabled: bool, is_accesskit_enabled: bool,
@ -377,7 +383,7 @@ impl Context {
&self, &self,
clip_rect: Rect, clip_rect: Rect,
item_spacing: Vec2, item_spacing: Vec2,
layer_id: AreaLayerId, layer: ZLayer,
id: Id, id: Id,
rect: Rect, rect: Rect,
sense: Sense, sense: Sense,
@ -394,7 +400,7 @@ impl Context {
// Respect clip rectangle when interacting // Respect clip rectangle when interacting
let interact_rect = clip_rect.intersect(interact_rect); let interact_rect = clip_rect.intersect(interact_rect);
let mut hovered = self.rect_contains_pointer(layer_id, interact_rect); let mut hovered = self.rect_contains_pointer(layer.area_layer, interact_rect);
// This solves the problem of overlapping widgets. // This solves the problem of overlapping widgets.
// Whichever widget is added LAST (=on top) gets the input: // Whichever widget is added LAST (=on top) gets the input:
@ -411,16 +417,18 @@ impl Context {
let mut slf = self.write(); let mut slf = self.write();
slf.layer_rects_this_frame slf.layer_rects_this_frame
.entry(layer_id) .entry(layer.area_layer)
.or_default() .or_default()
.push((id, interact_rect)); .push((id, layer.z, interact_rect));
if hovered { if hovered {
let pointer_pos = slf.input.pointer.interact_pos(); let pointer_pos = slf.input.pointer.interact_pos();
if let Some(pointer_pos) = pointer_pos { if let Some(pointer_pos) = pointer_pos {
if let Some(rects) = slf.layer_rects_prev_frame.get(&layer_id) { if let Some(rects) = slf.layer_rects_prev_frame.get_mut(&layer.area_layer) {
for &(prev_id, prev_rect) in rects.iter().rev() { rects.sort_by_key(|(_id, z, ..)| *z);
if prev_id == id {
for &(prev_id, prev_z, prev_rect) in rects.iter().rev() {
if prev_id == id && prev_z <= layer.z {
break; // there is no other interactive widget covering us at the pointer position. break; // there is no other interactive widget covering us at the pointer position.
} }
if prev_rect.contains(pointer_pos) { if prev_rect.contains(pointer_pos) {
@ -450,7 +458,7 @@ impl Context {
} }
} }
self.interact_with_hovered(layer_id, id, rect, sense, enabled, hovered) self.interact_with_hovered(layer.area_layer, id, rect, sense, enabled, hovered)
} }
/// You specify if a thing is hovered, and the function gives a [`Response`]. /// You specify if a thing is hovered, and the function gives a [`Response`].

View file

@ -224,6 +224,16 @@ impl ZLayer {
pub fn below_by(self, levels: i32) -> Self { pub fn below_by(self, levels: i32) -> Self {
self.with_z(self.z.below_by(levels)) self.with_z(self.z.below_by(levels))
} }
#[inline(always)]
pub fn id(&self) -> Id {
self.area_layer.id
}
#[inline(always)]
pub fn order(&self) -> Order {
self.area_layer.order
}
} }
/// A unique identifier of a specific [`Shape`] in a [`PaintList`]. /// A unique identifier of a specific [`Shape`] in a [`PaintList`].

View file

@ -140,6 +140,12 @@ impl Painter {
self.layer.area_layer self.layer.area_layer
} }
/// Where we paint, and on what Z-level
#[inline(always)]
pub fn zlayer(&self) -> ZLayer {
self.layer
}
#[inline(always)] #[inline(always)]
pub fn z(&self) -> ZOrder { pub fn z(&self) -> ZOrder {
self.layer.z self.layer.z

View file

@ -327,6 +327,11 @@ impl Ui {
self.painter().layer() self.painter().layer()
} }
#[inline]
pub fn layer(&self) -> ZLayer {
self.painter().zlayer()
}
/// The [`InputState`] of the [`Context`] associated with this [`Ui`]. /// The [`InputState`] of the [`Context`] associated with this [`Ui`].
/// Equivalent to `.ctx().input()`. /// Equivalent to `.ctx().input()`.
/// ///
@ -623,7 +628,7 @@ impl Ui {
self.ctx().interact( self.ctx().interact(
self.clip_rect(), self.clip_rect(),
self.spacing().item_spacing, self.spacing().item_spacing,
self.layer_id(), self.layer(),
id, id,
rect, rect,
sense, sense,