ruffle/core/src/focus_tracker.rs

45 lines
1.3 KiB
Rust
Raw Normal View History

use crate::avm1::Value;
use crate::context::UpdateContext;
pub use crate::display_object::{DisplayObject, TDisplayObject};
use gc_arena::{Collect, GcCell, MutationContext};
#[collect(no_drop)]
#[derive(Clone, Copy, Collect, Debug)]
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>>,
context: &mut UpdateContext<'_, 'gc, '_>,
) {
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 {
old.on_focus_changed(false);
}
if let Some(new) = focused_element {
new.on_focus_changed(true);
}
}
}