2022-08-19 14:14:37 +00:00
|
|
|
use crate::avm1::Avm1;
|
2022-08-19 13:11:05 +00:00
|
|
|
use crate::avm1::Value;
|
2020-10-29 23:09:57 +00:00
|
|
|
use crate::context::UpdateContext;
|
2021-04-15 03:29:12 +00:00
|
|
|
pub use crate::display_object::{DisplayObject, TDisplayObject, TDisplayObjectContainer};
|
2020-10-29 23:09:57 +00:00
|
|
|
use gc_arena::{Collect, GcCell, MutationContext};
|
|
|
|
|
2022-12-30 05:09:42 +00:00
|
|
|
#[derive(Clone, Copy, Collect)]
|
2021-02-12 13:03:17 +00:00
|
|
|
#[collect(no_drop)]
|
2020-10-29 23:09:57 +00:00
|
|
|
pub struct FocusTracker<'gc>(GcCell<'gc, Option<DisplayObject<'gc>>>);
|
|
|
|
|
|
|
|
impl<'gc> FocusTracker<'gc> {
|
|
|
|
pub fn new(gc_context: MutationContext<'gc, '_>) -> Self {
|
|
|
|
Self(GcCell::allocate(gc_context, None))
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get(&self) -> Option<DisplayObject<'gc>> {
|
|
|
|
*self.0.read()
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn set(
|
|
|
|
&self,
|
|
|
|
focused_element: Option<DisplayObject<'gc>>,
|
2023-01-06 23:33:31 +00:00
|
|
|
context: &mut UpdateContext<'_, 'gc>,
|
2020-10-29 23:09:57 +00:00
|
|
|
) {
|
|
|
|
let old = std::mem::replace(&mut *self.0.write(context.gc_context), focused_element);
|
|
|
|
|
|
|
|
if old.is_none() && focused_element.is_none() {
|
|
|
|
// We didn't have anything, we still don't, no change.
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if old.is_some() == focused_element.is_some()
|
|
|
|
&& old.unwrap().as_ptr() == focused_element.unwrap().as_ptr()
|
|
|
|
{
|
|
|
|
// We're setting it to the same object as before, no change.
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if let Some(old) = old {
|
2020-10-30 22:59:25 +00:00
|
|
|
old.on_focus_changed(context.gc_context, false);
|
2020-10-29 23:09:57 +00:00
|
|
|
}
|
|
|
|
if let Some(new) = focused_element {
|
2020-10-30 22:59:25 +00:00
|
|
|
new.on_focus_changed(context.gc_context, true);
|
2020-10-29 23:09:57 +00:00
|
|
|
}
|
2020-10-30 15:15:40 +00:00
|
|
|
|
2023-01-04 10:09:47 +00:00
|
|
|
tracing::info!("Focus is now on {:?}", focused_element);
|
2020-10-30 23:11:13 +00:00
|
|
|
|
2021-04-17 19:38:11 +00:00
|
|
|
let level0 = context.stage.root_clip();
|
2020-10-30 15:15:40 +00:00
|
|
|
Avm1::notify_system_listeners(
|
|
|
|
level0,
|
|
|
|
context,
|
2021-05-09 10:14:54 +00:00
|
|
|
"Selection".into(),
|
|
|
|
"onSetFocus".into(),
|
2020-10-30 15:15:40 +00:00
|
|
|
&[
|
|
|
|
old.map(|v| v.object()).unwrap_or(Value::Null),
|
|
|
|
focused_element.map(|v| v.object()).unwrap_or(Value::Null),
|
|
|
|
],
|
|
|
|
);
|
2020-10-29 23:09:57 +00:00
|
|
|
}
|
|
|
|
}
|