implement for interact
This commit is contained in:
parent
26c3fa22cb
commit
d0307417e1
5 changed files with 45 additions and 16 deletions
|
@ -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,
|
||||||
|
|
|
@ -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`].
|
||||||
|
|
|
@ -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`].
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in a new issue