core: `root` and `stage` should yield `None` if an inactive state child of an `Avm2Button` is involved in the parent chain.
This commit is contained in:
parent
169a99397a
commit
cfd95e3b3b
|
@ -1256,14 +1256,27 @@ pub trait TDisplayObject<'gc>:
|
||||||
/// version, see `avm1_root`.
|
/// version, see `avm1_root`.
|
||||||
fn avm2_root(&self, context: &mut UpdateContext<'_, 'gc, '_>) -> Option<DisplayObject<'gc>> {
|
fn avm2_root(&self, context: &mut UpdateContext<'_, 'gc, '_>) -> Option<DisplayObject<'gc>> {
|
||||||
let mut parent = Some((*self).into());
|
let mut parent = Some((*self).into());
|
||||||
|
if self.as_stage().is_some() {
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
|
||||||
while let Some(p) = parent {
|
while let Some(p) = parent {
|
||||||
let grandparent = p.avm2_parent();
|
let grandparent = p.parent();
|
||||||
|
|
||||||
if grandparent.is_none() {
|
if grandparent.is_none() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(gp_btn) = grandparent.and_then(|gp| gp.as_avm2_button()) {
|
||||||
|
let active_state = gp_btn.get_state_child(gp_btn.state().into());
|
||||||
|
if active_state
|
||||||
|
.map(|state| !DisplayObject::ptr_eq(state, p))
|
||||||
|
.unwrap_or(true)
|
||||||
|
{
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(gp) = grandparent {
|
if let Some(gp) = grandparent {
|
||||||
if gp.as_stage().is_some() {
|
if gp.as_stage().is_some() {
|
||||||
break;
|
break;
|
||||||
|
@ -1273,16 +1286,12 @@ pub trait TDisplayObject<'gc>:
|
||||||
parent = grandparent;
|
parent = grandparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(parent) = parent {
|
let movie = self.movie()?;
|
||||||
if !parent.is_on_stage(context) {
|
context
|
||||||
return None;
|
.library
|
||||||
}
|
.library_for_movie_mut(movie)
|
||||||
}
|
.root()
|
||||||
|
.or_else(|| parent.filter(|p| p.is_on_stage(context)))
|
||||||
parent.or_else(|| {
|
|
||||||
let movie = self.movie()?;
|
|
||||||
context.library.library_for_movie_mut(movie).root()
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Obtain the root of the display tree hierarchy, if a suitable object
|
/// Obtain the root of the display tree hierarchy, if a suitable object
|
||||||
|
@ -1296,14 +1305,22 @@ pub trait TDisplayObject<'gc>:
|
||||||
let mut parent = Some((*self).into());
|
let mut parent = Some((*self).into());
|
||||||
|
|
||||||
while let Some(p) = parent {
|
while let Some(p) = parent {
|
||||||
p.as_container()?;
|
let grandparent = p.parent();
|
||||||
|
|
||||||
let grandparent = p.avm2_parent();
|
|
||||||
|
|
||||||
if grandparent.is_none() {
|
if grandparent.is_none() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(gp_btn) = grandparent.and_then(|gp| gp.as_avm2_button()) {
|
||||||
|
let active_state = gp_btn.get_state_child(gp_btn.state().into());
|
||||||
|
if active_state
|
||||||
|
.map(|state| !DisplayObject::ptr_eq(state, p))
|
||||||
|
.unwrap_or(true)
|
||||||
|
{
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
parent = grandparent;
|
parent = grandparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -256,6 +256,11 @@ impl<'gc> Avm2Button<'gc> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the rendered state of the button.
|
||||||
|
pub fn state(self) -> ButtonState {
|
||||||
|
self.0.read().state
|
||||||
|
}
|
||||||
|
|
||||||
/// Change the rendered state of the button.
|
/// Change the rendered state of the button.
|
||||||
pub fn set_state(self, context: &mut UpdateContext<'_, 'gc, '_>, state: ButtonState) {
|
pub fn set_state(self, context: &mut UpdateContext<'_, 'gc, '_>, state: ButtonState) {
|
||||||
self.0.write(context.gc_context).state = state;
|
self.0.write(context.gc_context).state = state;
|
||||||
|
|
Loading…
Reference in New Issue