avm1: Add EditText variable property
Add `EditText::variable` as well as `TextField.variable` property. This commit only adds the getter/setter and does not yet add the binding functionality.
This commit is contained in:
parent
dd50071240
commit
a922fd559f
|
@ -312,6 +312,46 @@ pub fn set_multiline<'gc>(
|
|||
Ok(Value::Undefined.into())
|
||||
}
|
||||
|
||||
fn variable<'gc>(
|
||||
_avm: &mut Avm1<'gc>,
|
||||
_context: &mut UpdateContext<'_, 'gc, '_>,
|
||||
this: Object<'gc>,
|
||||
_args: &[Value<'gc>],
|
||||
) -> Result<ReturnValue<'gc>, Error<'gc>> {
|
||||
if let Some(etext) = this
|
||||
.as_display_object()
|
||||
.and_then(|dobj| dobj.as_edit_text())
|
||||
{
|
||||
if let Some(variable) = etext.variable() {
|
||||
return Ok(variable.to_string().into());
|
||||
}
|
||||
}
|
||||
|
||||
// Unset `variable` retuns null, not undefined
|
||||
Ok(Value::Null.into())
|
||||
}
|
||||
|
||||
fn set_variable<'gc>(
|
||||
avm: &mut Avm1<'gc>,
|
||||
context: &mut UpdateContext<'_, 'gc, '_>,
|
||||
this: Object<'gc>,
|
||||
args: &[Value<'gc>],
|
||||
) -> Result<ReturnValue<'gc>, Error<'gc>> {
|
||||
let variable = match args.get(0) {
|
||||
None | Some(Value::Undefined) | Some(Value::Null) => None,
|
||||
Some(v) => Some(v.coerce_to_string(avm, context)?),
|
||||
};
|
||||
|
||||
if let Some(etext) = this
|
||||
.as_display_object()
|
||||
.and_then(|dobj| dobj.as_edit_text())
|
||||
{
|
||||
etext.set_variable(variable.map(|v| v.into_owned()), context);
|
||||
}
|
||||
|
||||
Ok(Value::Undefined.into())
|
||||
}
|
||||
|
||||
pub fn word_wrap<'gc>(
|
||||
_avm: &mut Avm1<'gc>,
|
||||
_context: &mut UpdateContext<'_, 'gc, '_>,
|
||||
|
@ -469,6 +509,13 @@ pub fn attach_virtual_properties<'gc>(gc_context: MutationContext<'gc, '_>, obje
|
|||
Some(Executable::Native(set_multiline)),
|
||||
ReadOnly.into(),
|
||||
);
|
||||
object.add_property(
|
||||
gc_context,
|
||||
"variable",
|
||||
Executable::Native(variable),
|
||||
Some(Executable::Native(set_variable)),
|
||||
DontDelete | ReadOnly | DontEnum,
|
||||
);
|
||||
object.add_property(
|
||||
gc_context,
|
||||
"wordWrap",
|
||||
|
|
|
@ -12,7 +12,7 @@ use crate::tag_utils::SwfMovie;
|
|||
use crate::transform::Transform;
|
||||
use crate::xml::XMLDocument;
|
||||
use gc_arena::{Collect, Gc, GcCell, MutationContext};
|
||||
use std::sync::Arc;
|
||||
use std::{cell::Ref, sync::Arc};
|
||||
use swf::Twips;
|
||||
|
||||
/// Boxed error type.
|
||||
|
@ -99,6 +99,9 @@ pub struct EditTextData<'gc> {
|
|||
|
||||
/// The AVM1 object handle
|
||||
object: Option<Object<'gc>>,
|
||||
|
||||
/// The variable path that this text field is bound to (AVM1 only).
|
||||
variable: Option<String>,
|
||||
}
|
||||
|
||||
impl<'gc> EditText<'gc> {
|
||||
|
@ -146,6 +149,12 @@ impl<'gc> EditText<'gc> {
|
|||
base.matrix_mut(context.gc_context).tx = bounds.x_min;
|
||||
base.matrix_mut(context.gc_context).ty = bounds.y_min;
|
||||
|
||||
let variable = if !swf_tag.variable_name.is_empty() {
|
||||
Some(swf_tag.variable_name.clone())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let et = EditText(GcCell::allocate(
|
||||
context.gc_context,
|
||||
EditTextData {
|
||||
|
@ -169,6 +178,7 @@ impl<'gc> EditText<'gc> {
|
|||
intrinsic_bounds,
|
||||
bounds,
|
||||
autosize: AutoSizeMode::None,
|
||||
variable,
|
||||
},
|
||||
));
|
||||
|
||||
|
@ -405,6 +415,26 @@ impl<'gc> EditText<'gc> {
|
|||
base_width
|
||||
}
|
||||
|
||||
/// Returns the variable that this text field is bound to.
|
||||
pub fn variable(&self) -> Option<Ref<str>> {
|
||||
let text = self.0.read();
|
||||
if text.variable.is_some() {
|
||||
Some(Ref::map(text, |text| text.variable.as_deref().unwrap()))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_variable(self, variable: Option<String>, context: &mut UpdateContext<'_, 'gc, '_>) {
|
||||
self.0.write(context.gc_context).variable = variable
|
||||
}
|
||||
|
||||
/// Construct a base text transform for this `EditText`, to be used for
|
||||
/// evaluating fonts.
|
||||
///
|
||||
/// The `text_transform` constitutes the base transform that all text is
|
||||
/// written into.
|
||||
|
||||
/// Redraw the border of this `EditText`.
|
||||
fn redraw_border(self, context: MutationContext<'gc, '_>) {
|
||||
let mut write = self.0.write(context);
|
||||
|
|
Loading…
Reference in New Issue