avm2: Implement TextField.maxChars
This commit is contained in:
parent
f83c573734
commit
fb4d2d3f04
|
@ -1241,6 +1241,41 @@ pub fn set_scroll_h<'gc>(
|
||||||
Ok(Value::Undefined)
|
Ok(Value::Undefined)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn max_chars<'gc>(
|
||||||
|
_activation: &mut Activation<'_, 'gc>,
|
||||||
|
this: Option<Object<'gc>>,
|
||||||
|
_args: &[Value<'gc>],
|
||||||
|
) -> Result<Value<'gc>, Error<'gc>> {
|
||||||
|
if let Some(this) = this
|
||||||
|
.and_then(|this| this.as_display_object())
|
||||||
|
.and_then(|this| this.as_edit_text())
|
||||||
|
{
|
||||||
|
return Ok(this.max_chars().into());
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Value::Undefined)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_max_chars<'gc>(
|
||||||
|
activation: &mut Activation<'_, 'gc>,
|
||||||
|
this: Option<Object<'gc>>,
|
||||||
|
args: &[Value<'gc>],
|
||||||
|
) -> Result<Value<'gc>, Error<'gc>> {
|
||||||
|
if let Some(this) = this
|
||||||
|
.and_then(|this| this.as_display_object())
|
||||||
|
.and_then(|this| this.as_edit_text())
|
||||||
|
{
|
||||||
|
let input = args
|
||||||
|
.get(0)
|
||||||
|
.cloned()
|
||||||
|
.unwrap_or(Value::Undefined)
|
||||||
|
.coerce_to_i32(activation)?;
|
||||||
|
this.set_max_chars(input, &mut activation.context);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Value::Undefined)
|
||||||
|
}
|
||||||
|
|
||||||
/// Construct `TextField`'s class.
|
/// Construct `TextField`'s class.
|
||||||
pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
|
pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
|
||||||
let class = Class::new(
|
let class = Class::new(
|
||||||
|
@ -1288,6 +1323,7 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
||||||
("length", Some(length), None),
|
("length", Some(length), None),
|
||||||
("maxScrollH", Some(max_scroll_h), None),
|
("maxScrollH", Some(max_scroll_h), None),
|
||||||
("maxScrollV", Some(max_scroll_v), None),
|
("maxScrollV", Some(max_scroll_v), None),
|
||||||
|
("maxChars", Some(max_chars), Some(set_max_chars)),
|
||||||
("multiline", Some(multiline), Some(set_multiline)),
|
("multiline", Some(multiline), Some(set_multiline)),
|
||||||
("scrollH", Some(scroll_h), Some(set_scroll_h)),
|
("scrollH", Some(scroll_h), Some(set_scroll_h)),
|
||||||
("scrollV", Some(scroll_v), Some(set_scroll_v)),
|
("scrollV", Some(scroll_v), Some(set_scroll_v)),
|
||||||
|
|
|
@ -133,6 +133,10 @@ pub struct EditTextData<'gc> {
|
||||||
/// How many lines down the text is offset by. 1-based index.
|
/// How many lines down the text is offset by. 1-based index.
|
||||||
scroll: usize,
|
scroll: usize,
|
||||||
|
|
||||||
|
/// The limit of characters that can be manually input by the user.
|
||||||
|
/// Doesn't affect script-triggered modifications.
|
||||||
|
max_chars: i32,
|
||||||
|
|
||||||
/// Flags indicating the text field's settings.
|
/// Flags indicating the text field's settings.
|
||||||
flags: EditTextFlag,
|
flags: EditTextFlag,
|
||||||
}
|
}
|
||||||
|
@ -278,6 +282,7 @@ impl<'gc> EditText<'gc> {
|
||||||
hscroll: 0.0,
|
hscroll: 0.0,
|
||||||
line_data,
|
line_data,
|
||||||
scroll: 1,
|
scroll: 1,
|
||||||
|
max_chars: 0,
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
|
|
||||||
|
@ -1122,6 +1127,14 @@ impl<'gc> EditText<'gc> {
|
||||||
self.0.write(context.gc_context).scroll = clamped;
|
self.0.write(context.gc_context).scroll = clamped;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn max_chars(self) -> i32 {
|
||||||
|
self.0.read().max_chars
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_max_chars(self, value: i32, context: &mut UpdateContext<'_, 'gc>) {
|
||||||
|
self.0.write(context.gc_context).max_chars = value;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn screen_position_to_index(self, position: (Twips, Twips)) -> Option<usize> {
|
pub fn screen_position_to_index(self, position: (Twips, Twips)) -> Option<usize> {
|
||||||
let text = self.0.read();
|
let text = self.0.read();
|
||||||
let position = self.global_to_local(position);
|
let position = self.global_to_local(position);
|
||||||
|
@ -1212,18 +1225,30 @@ impl<'gc> EditText<'gc> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
code if !(code as char).is_control() => {
|
code if !(code as char).is_control() => {
|
||||||
self.replace_text(
|
let can_insert = {
|
||||||
selection.start(),
|
let read = self.0.read();
|
||||||
selection.end(),
|
let max_chars = read.max_chars;
|
||||||
&WString::from_char(character),
|
if max_chars == 0 {
|
||||||
context,
|
true
|
||||||
);
|
} else {
|
||||||
let new_start = selection.start() + character.len_utf8();
|
let text_len = read.text_spans.text().len();
|
||||||
self.set_selection(
|
text_len < max_chars.max(0) as usize
|
||||||
Some(TextSelection::for_position(new_start)),
|
}
|
||||||
context.gc_context,
|
};
|
||||||
);
|
if can_insert {
|
||||||
changed = true;
|
self.replace_text(
|
||||||
|
selection.start(),
|
||||||
|
selection.end(),
|
||||||
|
&WString::from_char(character),
|
||||||
|
context,
|
||||||
|
);
|
||||||
|
let new_start = selection.start() + character.len_utf8();
|
||||||
|
self.set_selection(
|
||||||
|
Some(TextSelection::for_position(new_start)),
|
||||||
|
context.gc_context,
|
||||||
|
);
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue