core: Add stub of ContextMenuItem
This commit is contained in:
parent
c8fefc56b5
commit
f3aa6f7f01
|
@ -40,6 +40,7 @@ pub(crate) mod text_field;
|
|||
mod text_format;
|
||||
mod xml;
|
||||
pub(crate) mod context_menu;
|
||||
pub(crate) mod context_menu_item;
|
||||
|
||||
#[allow(non_snake_case, unused_must_use)] //can't use errors yet
|
||||
pub fn getURL<'a, 'gc>(
|
||||
|
@ -316,6 +317,8 @@ pub fn create_globals<'gc>(
|
|||
let object = object::create_object_object(gc_context, object_proto, function_proto);
|
||||
|
||||
let context_menu_proto = context_menu::create_proto(gc_context, object_proto, function_proto);
|
||||
let context_menu_item_proto = context_menu_item::create_proto(gc_context, object_proto, function_proto);
|
||||
|
||||
|
||||
let button = FunctionObject::function(
|
||||
gc_context,
|
||||
|
@ -459,11 +462,27 @@ pub fn create_globals<'gc>(
|
|||
EnumSet::empty(),
|
||||
);
|
||||
|
||||
let context_menu = context_menu::create_context_menu_object(gc_context, Some(context_menu_proto), Some(function_proto));
|
||||
globals.define_value(
|
||||
gc_context,
|
||||
"ContextMenu",
|
||||
context_menu.into(),
|
||||
FunctionObject::function(
|
||||
gc_context,
|
||||
Executable::Native(context_menu::constructor),
|
||||
Some(function_proto),
|
||||
Some(context_menu_proto),
|
||||
).into(),
|
||||
EnumSet::empty()
|
||||
);
|
||||
|
||||
globals.define_value(
|
||||
gc_context,
|
||||
"ContextMenuItem",
|
||||
FunctionObject::function(
|
||||
gc_context,
|
||||
Executable::Native(context_menu_item::constructor),
|
||||
Some(function_proto),
|
||||
Some(context_menu_item_proto),
|
||||
).into(),
|
||||
EnumSet::empty()
|
||||
);
|
||||
|
||||
|
|
|
@ -1,60 +1,81 @@
|
|||
use gc_arena::MutationContext;
|
||||
use crate::avm1::{Value, ScriptObject, Avm1};
|
||||
use crate::avm1::function::{FunctionObject, Executable};
|
||||
use crate::avm1::{Value, ScriptObject};
|
||||
use crate::avm1::Object;
|
||||
use crate::context::UpdateContext;
|
||||
use crate::avm1::return_value::ReturnValue;
|
||||
use crate::avm1::error::Error;
|
||||
use enumset::EnumSet;
|
||||
use crate::avm1::activation::Activation;
|
||||
use crate::avm1::object::TObject;
|
||||
|
||||
//TODO: in future this will want to be a custom object, as it has a callback function in constructor arg
|
||||
//TODO: note: callback should be called when menu is opened but before it is displayed
|
||||
//TODO: check for hidden props
|
||||
//TODO: there shuold be a menu prop somewhere (as2:444)
|
||||
|
||||
pub fn constructor<'gc>(
|
||||
_avm: &mut Avm1<'gc>,
|
||||
_context: &mut UpdateContext<'_, 'gc, '_>,
|
||||
_this: Object<'gc>,
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
context: &mut UpdateContext<'_, 'gc, '_>,
|
||||
this: Object<'gc>,
|
||||
_args: &[Value<'gc>],
|
||||
) -> Result<ReturnValue<'gc>, Error> {
|
||||
) -> Result<Value<'gc>, Error<'gc>> {
|
||||
let obj_proto = activation.avm().prototypes.object;
|
||||
let built_in_items = obj_proto.new(activation, context, obj_proto, &[])?;
|
||||
let _ = crate::avm1::globals::object::constructor(activation, context, built_in_items, &[]);
|
||||
//TODO Check that this lines up with FP
|
||||
built_in_items.set("zoom", true.into(), activation, context)?;
|
||||
built_in_items.set("quality", true.into(), activation, context)?;
|
||||
built_in_items.set("play", true.into(), activation, context)?;
|
||||
built_in_items.set("loop", true.into(), activation, context)?;
|
||||
built_in_items.set("rewind", true.into(), activation, context)?;
|
||||
built_in_items.set("forward_back", true.into(), activation, context)?;
|
||||
built_in_items.set("print", true.into(), activation, context)?;
|
||||
|
||||
//TODO: check if these are on the proto or not
|
||||
//TODO: are they virt?
|
||||
this.set("builtInItems", built_in_items.into(), activation, context)?;
|
||||
|
||||
let array_proto = activation.avm().prototypes.array;
|
||||
let custom_items = array_proto.new(activation, context, array_proto, &[])?;
|
||||
let _ = crate::avm1::globals::array::constructor(activation, context, custom_items, &[]);
|
||||
|
||||
this.set("customItems", custom_items.into(), activation, context)?;
|
||||
|
||||
Ok(Value::Undefined.into())
|
||||
}
|
||||
|
||||
pub fn create_context_menu_object<'gc>(
|
||||
gc_context: MutationContext<'gc, '_>,
|
||||
context_menu_proto: Option<Object<'gc>>,
|
||||
fn_proto: Option<Object<'gc>>,
|
||||
) -> Object<'gc> {
|
||||
FunctionObject::function(
|
||||
gc_context,
|
||||
Executable::Native(constructor),
|
||||
fn_proto,
|
||||
context_menu_proto,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn copy<'gc>(
|
||||
_avm: &mut Avm1<'gc>,
|
||||
_activation: &mut Activation<'_, 'gc>,
|
||||
_context: &mut UpdateContext<'_, 'gc, '_>,
|
||||
_this: Object<'gc>,
|
||||
_args: &[Value<'gc>],
|
||||
) -> Result<ReturnValue<'gc>, Error> {
|
||||
) -> Result<Value<'gc>, Error<'gc>> {
|
||||
log::warn!("ContextMenu.copy() not implemented");
|
||||
Ok(Value::Undefined.into())
|
||||
}
|
||||
|
||||
pub fn hide_builtin_items<'gc>(
|
||||
_avm: &mut Avm1<'gc>,
|
||||
_context: &mut UpdateContext<'_, 'gc, '_>,
|
||||
_this: Object<'gc>,
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
context: &mut UpdateContext<'_, 'gc, '_>,
|
||||
this: Object<'gc>,
|
||||
_args: &[Value<'gc>],
|
||||
) -> Result<ReturnValue<'gc>, Error> {
|
||||
log::warn!("ContextMenu.hideBuiltInItems() not implemented");
|
||||
) -> Result<Value<'gc>, Error<'gc>> {
|
||||
let built_in_items = this.get("builtInItems", activation, context)?.coerce_to_object(activation, context);
|
||||
built_in_items.set("zoom", false.into(), activation, context)?;
|
||||
built_in_items.set("quality", false.into(), activation, context)?;
|
||||
built_in_items.set("play", false.into(), activation, context)?;
|
||||
built_in_items.set("loop", false.into(), activation, context)?;
|
||||
built_in_items.set("rewind", false.into(), activation, context)?;
|
||||
built_in_items.set("forward_back", false.into(), activation, context)?;
|
||||
built_in_items.set("print", false.into(), activation, context)?;
|
||||
Ok(Value::Undefined.into())
|
||||
}
|
||||
|
||||
pub fn on_select<'gc>(
|
||||
_avm: &mut Avm1<'gc>,
|
||||
_activation: &mut Activation<'_, 'gc>,
|
||||
_context: &mut UpdateContext<'_, 'gc, '_>,
|
||||
_this: Object<'gc>,
|
||||
_args: &[Value<'gc>],
|
||||
) -> Result<ReturnValue<'gc>, Error> {
|
||||
) -> Result<Value<'gc>, Error<'gc>> {
|
||||
log::warn!("ContextMenu.onSelect() not implemented");
|
||||
Ok(Value::Undefined.into())
|
||||
}
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
use gc_arena::MutationContext;
|
||||
use crate::avm1::{Value, ScriptObject};
|
||||
use crate::avm1::Object;
|
||||
use crate::context::UpdateContext;
|
||||
use crate::avm1::error::Error;
|
||||
use enumset::EnumSet;
|
||||
use crate::avm1::activation::Activation;
|
||||
use crate::avm1::object::TObject;
|
||||
|
||||
// TODO: should appear at the top of the context menu with a seperator between it and built ins
|
||||
//TODO: Max 15 custom items/context menu
|
||||
//TODO: items must have a visible name (at leat one char, not whitespace/newline/control)
|
||||
//TODO: length <= 100
|
||||
//TODO: can't be the same as an existing item (custom or otherwise)
|
||||
//TODO: two items are the same if they have the same caption, ignoing case, punctuation and whitespace
|
||||
|
||||
|
||||
pub fn constructor<'gc>(
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
context: &mut UpdateContext<'_, 'gc, '_>,
|
||||
this: Object<'gc>,
|
||||
args: &[Value<'gc>],
|
||||
) -> Result<Value<'gc>, Error<'gc>> {
|
||||
let caption = args.get(0)
|
||||
.unwrap_or(&Value::Undefined)
|
||||
.to_owned()
|
||||
.coerce_to_string(activation, context)?
|
||||
.to_string();
|
||||
let _callback = args.get(1)
|
||||
.unwrap_or(&Value::Undefined)
|
||||
.to_owned()
|
||||
.coerce_to_object(activation, context);
|
||||
let separator_before = args.get(2)
|
||||
.unwrap_or(&Value::Bool(false))
|
||||
.to_owned()
|
||||
.as_bool(activation.swf_version());
|
||||
let enabled = args.get(3)
|
||||
.unwrap_or(&Value::Bool(true))
|
||||
.to_owned()
|
||||
.as_bool(activation.swf_version());
|
||||
let visible = args.get(4)
|
||||
.unwrap_or(&Value::Bool(true))
|
||||
.to_owned()
|
||||
.as_bool(activation.swf_version());
|
||||
|
||||
//TODO: check for virt
|
||||
this.set("caption", caption.into(), activation, context)?;
|
||||
this.set("enabled", enabled.into(), activation, context)?;
|
||||
this.set("separatorBefore", separator_before.into(), activation, context)?;
|
||||
this.set("visible", visible.into(), activation, context)?;
|
||||
|
||||
Ok(Value::Undefined.into())
|
||||
}
|
||||
|
||||
pub fn copy<'gc>(
|
||||
_activation: &mut Activation<'_, 'gc>,
|
||||
_context: &mut UpdateContext<'_, 'gc, '_>,
|
||||
_this: Object<'gc>,
|
||||
_args: &[Value<'gc>],
|
||||
) -> Result<Value<'gc>, Error<'gc>> {
|
||||
log::warn!("ContextMenuItem.copy() not implemented");
|
||||
Ok(Value::Undefined.into())
|
||||
}
|
||||
|
||||
pub fn on_select<'gc>(
|
||||
_activation: &mut Activation<'_, 'gc>,
|
||||
_context: &mut UpdateContext<'_, 'gc, '_>,
|
||||
_this: Object<'gc>,
|
||||
_args: &[Value<'gc>],
|
||||
) -> Result<Value<'gc>, Error<'gc>> {
|
||||
log::warn!("ContextMenuItem.onSelect() not implemented");
|
||||
Ok(Value::Undefined.into())
|
||||
}
|
||||
|
||||
pub fn create_proto<'gc>(
|
||||
gc_context: MutationContext<'gc, '_>,
|
||||
proto: Object<'gc>,
|
||||
fn_proto: Object<'gc>,
|
||||
) -> Object<'gc> {
|
||||
let mut object = ScriptObject::object(gc_context, Some(proto));
|
||||
|
||||
object.force_set_function(
|
||||
"copy",
|
||||
copy,
|
||||
gc_context,
|
||||
EnumSet::empty(),
|
||||
Some(fn_proto)
|
||||
);
|
||||
|
||||
object.force_set_function(
|
||||
"onSelect",
|
||||
on_select,
|
||||
gc_context,
|
||||
EnumSet::empty(),
|
||||
Some(fn_proto)
|
||||
);
|
||||
|
||||
object.into()
|
||||
}
|
Loading…
Reference in New Issue