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 is the foundation for windows and popups.
use crate::*;
use crate::{layers::ZLayer, *};
/// State that is persisted between frames.
// 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(
Rect::EVERYTHING,
ctx.style().spacing.item_spacing,
layer_id,
ZLayer::from_area_layer(layer_id),
interact_id,
state.rect(),
sense,

View file

@ -2,9 +2,15 @@
use std::sync::Arc;
use crate::{
animation_manager::AnimationManager, data::output::PlatformOutput, frame_state::FrameState,
input_state::*, layers::GraphicLayers, memory::Options, os::OperatingSystem,
output::FullOutput, TextureHandle, *,
animation_manager::AnimationManager,
data::output::PlatformOutput,
frame_state::FrameState,
input_state::*,
layers::{GraphicLayers, ZLayer, ZOrder},
memory::Options,
os::OperatingSystem,
output::FullOutput,
TextureHandle, *,
};
use epaint::{mutex::*, stats::*, text::Fonts, TessellationOptions, *};
@ -64,9 +70,9 @@ struct ContextImpl {
requested_repaint_last_frame: bool,
/// 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
layer_rects_prev_frame: ahash::HashMap<AreaLayerId, Vec<(Id, Rect)>>,
layer_rects_prev_frame: ahash::HashMap<AreaLayerId, Vec<(Id, ZOrder, Rect)>>,
#[cfg(feature = "accesskit")]
is_accesskit_enabled: bool,
@ -377,7 +383,7 @@ impl Context {
&self,
clip_rect: Rect,
item_spacing: Vec2,
layer_id: AreaLayerId,
layer: ZLayer,
id: Id,
rect: Rect,
sense: Sense,
@ -394,7 +400,7 @@ impl Context {
// Respect clip rectangle when interacting
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.
// Whichever widget is added LAST (=on top) gets the input:
@ -411,16 +417,18 @@ impl Context {
let mut slf = self.write();
slf.layer_rects_this_frame
.entry(layer_id)
.entry(layer.area_layer)
.or_default()
.push((id, interact_rect));
.push((id, layer.z, interact_rect));
if hovered {
let pointer_pos = slf.input.pointer.interact_pos();
if let Some(pointer_pos) = pointer_pos {
if let Some(rects) = slf.layer_rects_prev_frame.get(&layer_id) {
for &(prev_id, prev_rect) in rects.iter().rev() {
if prev_id == id {
if let Some(rects) = slf.layer_rects_prev_frame.get_mut(&layer.area_layer) {
rects.sort_by_key(|(_id, z, ..)| *z);
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.
}
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`].

View file

@ -224,6 +224,16 @@ impl ZLayer {
pub fn below_by(self, levels: i32) -> Self {
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`].

View file

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

View file

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