Add scoped overlay hosts
This commit is contained in:
1 parent
a33fbca966
commit
44a5da378b
14 files changed
+882
-27
No files matched your search
@@ -14,6 +14,10 @@ impl ControllerId {
|
||||
pub fn host(self) -> WidgetId {
|
||||
self.host
|
||||
}
|
||||
|
||||
pub fn is<C: 'static>(self) -> bool {
|
||||
self.kind == TypeId::of::<C>()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
@@ -44,6 +48,10 @@ pub trait Controller<Rsc>: ControllerValue {
|
||||
fn command(&mut self, _command: Command, _rsc: &mut Rsc) -> CommandResult {
|
||||
CommandResult::Unused
|
||||
}
|
||||
|
||||
fn blocks_prior_input(&self) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ControllerManager<Rsc> {
|
||||
@@ -206,6 +214,16 @@ impl<Rsc: 'static> ControllerManager<Rsc> {
|
||||
self.command_target
|
||||
}
|
||||
|
||||
pub fn command_target_blocks_input(&self) -> bool {
|
||||
let Some(id) = self.command_target else {
|
||||
return false;
|
||||
};
|
||||
self.by_widget
|
||||
.get(&id.host)
|
||||
.and_then(|controllers| controllers.get(&id.kind))
|
||||
.is_some_and(|controller| controller.blocks_prior_input())
|
||||
}
|
||||
|
||||
pub(crate) fn command_target_revision(&self) -> u64 {
|
||||
self.command_target_revision
|
||||
}
|
||||
@@ -214,6 +232,18 @@ impl<Rsc: 'static> ControllerManager<Rsc> {
|
||||
self.command_boundary
|
||||
}
|
||||
|
||||
pub(crate) fn is_below(&self, mut widget: WidgetId, ancestor: WidgetId) -> bool {
|
||||
loop {
|
||||
let Some(parent) = self.parents.get(&widget).copied().flatten() else {
|
||||
return false;
|
||||
};
|
||||
if parent == ancestor {
|
||||
return true;
|
||||
}
|
||||
widget = parent;
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn set_command_boundary(&mut self, boundary: Option<WidgetId>) {
|
||||
self.command_boundary = boundary;
|
||||
}
|
||||
|
||||
@@ -54,13 +54,12 @@ pub trait HasEvents: Sized + UiRsc + HasState {
|
||||
|
||||
fn run_command(&mut self, command: Command) -> CommandResult {
|
||||
let revision = self.events().controllers.command_target_revision();
|
||||
if self
|
||||
.events()
|
||||
.controllers
|
||||
.command_target()
|
||||
.is_some_and(|target| {
|
||||
self.events().controllers.command_boundary() == Some(target.host())
|
||||
})
|
||||
if let Some(boundary) = self.events().controllers.command_boundary()
|
||||
&& self
|
||||
.events()
|
||||
.controllers
|
||||
.command_target()
|
||||
.is_none_or(|target| !self.events().controllers.is_below(target.host(), boundary))
|
||||
{
|
||||
return CommandResult::Unused;
|
||||
}
|
||||
|
||||
@@ -22,14 +22,14 @@ pub trait WidgetLike<Rsc: UiRsc, Tag>: Sized {
|
||||
}
|
||||
}
|
||||
|
||||
fn set_root(self, rsc: &mut Rsc, root: &mut impl HasRoot) {
|
||||
fn set_root(self, rsc: &mut Rsc, root: &mut impl HasRoot<Rsc>) {
|
||||
let id = self.add_strong(rsc);
|
||||
root.set_root(id);
|
||||
root.set_root(rsc, id);
|
||||
}
|
||||
}
|
||||
|
||||
pub trait HasRoot {
|
||||
fn set_root(&mut self, root: StrongWidget);
|
||||
pub trait HasRoot<Rsc> {
|
||||
fn set_root(&mut self, rsc: &mut Rsc, root: StrongWidget);
|
||||
}
|
||||
|
||||
pub trait WidgetArrLike<Rsc, const LEN: usize, Tag> {
|
||||
|
||||
Reference in new issue
Block a user