/// Construct a given state of the button and return it's containing
/// DisplayObject.
///
/// In contrast to AVM1Button, the AVM2 variety constructs all of it's
/// children once and stores them in four named slots, either on their own
/// (if they are singular) or in `Sprite`s created specifically to store
/// button children. This means that, for example, a child that exists in
/// multiple states in the SWF will actually be instantiated multiple
/// times.
///
/// If the boolean parameter is `true`, then the caller of this function
/// should signal events on all children of the returned display object.
Construct a given state of the button and return it's containing
DisplayObject.

In contrast to AVM1Button, the AVM2 variety constructs all of it's
children once and stores them in four named slots, either on their own
(if they are singular) or in `Sprite`s created specifically to store
button children. This means that, for example, a child that exists in
multiple states in the SWF will actually be instantiated multiple
times.

If the boolean parameter is `true`, then the caller of this function
should signal events on all children of the returned display object.
Construct a given state of the button and return it ' s containing DisplayObject . In contrast to AVM1Button the AVM2 variety constructs all of it ' s children once and stores them in four named slots either on their own ( if they are singular ) or in ` Sprite ` s created specifically to store button children . This means that for example a child that exists in multiple states in the SWF will actually be instantiated multiple times . If the boolean parameter is ` true ` then the caller of this function should signal events on all children of the returned display object .
fn create_state(
        self,
        context: &mut UpdateContext<'_, 'gc, '_>,
        swf_state: swf::ButtonState,
    ) -> (DisplayObject<'gc>, bool) {
        let movie = self
            .movie()
            .expect("All SWF-defined buttons should have movies");
        let sprite_class = context.avm2.classes().sprite;
        let mut children = Vec::new();
        let static_data = self.0.read().static_data;
        for record in static_data.read().records.iter() {
            if record.states.contains(swf_state) {
                match context
                    .library
                    .library_for_movie_mut(movie.clone())
                    .instantiate_by_id(record.id, context.gc_context)
                {
                    Ok(child) => {
                        child.set_matrix(context.gc_context, &record.matrix.into());
                        child.set_depth(context.gc_context, record.depth.into());
                        if swf_state != swf::ButtonState::HIT_TEST {
                            child.set_color_transform(
                                context.gc_context,
                                &record.color_transform.clone().into(),
                            );
                        }
                        children.push((child, record.depth));
                    }
                    Err(error) => {
                        log::error!(
                            "Button ID {}: could not instantiate child ID {}: {}",
                            static_data.read().id,
                            record.id,
                            error
                        );
                    }
                };
            }
        }
        if children.len() == 1 {
            let child = children.first().cloned().unwrap().0;
            child.set_parent(context.gc_context, Some(self.into()));
            child.post_instantiation(context, None, Instantiator::Movie, false);
            child.construct_frame(context);
            (child, false)
        } else {
            let state_sprite = MovieClip::new(movie, context.gc_context);
            state_sprite.set_avm2_class(context.gc_context, Some(sprite_class));
            state_sprite.set_parent(context.gc_context, Some(self.into()));
            state_sprite.construct_frame(context);
            for (child, depth) in children {
                // `parent` returns `null` for these grandchildren during construction time, even though
                // `stage` and `root` will be defined. Set the parent temporarily to the button itself so
                // that `parent` is `null` (`DisplayObject::avm2_parent` checks that the parent is a container),
                // and then properly set the parent to the state Sprite afterwards.
                state_sprite.replace_at_depth(context, child, depth.into());
                child.set_parent(context.gc_context, Some(self.into()));
                child.post_instantiation(context, None, Instantiator::Movie, false);
                child.construct_frame(context);
                child.set_parent(context.gc_context, Some(state_sprite.into()));
            }
            (state_sprite.into(), true)
        }
    }
fn create_state ( self , context : & mut UpdateContext < ' _ , ' gc , ' _ > , swf_state : swf :: ButtonState , ) -> ( DisplayObject < ' gc > , bool ) { let movie = self . movie ( ) . expect ( " " ) ; let sprite_class = context . avm2 . classes ( ) . sprite ; let mut children = Vec :: new ( ) ; let static_data = self . 0 . read ( ) . static_data ; for record in static_data . read ( ) . records . iter ( ) { if record . states . contains ( swf_state ) { match context . library . library_for_movie_mut ( movie . clone ( ) ) . instantiate_by_id ( record . id , context . gc_context ) { Ok ( child ) => { child . set_matrix ( context . gc_context , & record . matrix . into ( ) ) ; child . set_depth ( context . gc_context , record . depth . into ( ) ) ; if swf_state != swf :: ButtonState :: HIT_TEST { child . set_color_transform ( context . gc_context , & record . color_transform . clone ( ) . into ( ) , ) ; } children . push ( ( child , record . depth ) ) ; } Err ( error ) => { log :: error ! ( " " static_data read ( ) id record id error ) ; } } ; } } if children . len ( ) == 1 { let child = children . first ( ) . cloned ( ) . unwrap ( ) . 0 ; child . set_parent ( context . gc_context , Some ( self . into ( ) ) ) ; child . post_instantiation ( context , None , Instantiator :: Movie , false ) ; child . construct_frame ( context ) ; ( child , false ) } else { let state_sprite = MovieClip :: new ( movie , context . gc_context ) ; state_sprite . set_avm2_class ( context . gc_context , Some ( sprite_class ) ) ; state_sprite . set_parent ( context . gc_context , Some ( self . into ( ) ) ) ; state_sprite . construct_frame ( context ) ; for ( child , depth ) in children { // `parent` returns `null` for these grandchildren during construction time, even though // `stage` and `root` will be defined. Set the parent temporarily to the button itself so // that `parent` is `null` (`DisplayObject::avm2_parent` checks that the parent is a container), // and then properly set the parent to the state Sprite afterwards. state_sprite . replace_at_depth ( context , child , depth . into ( ) ) ; child . set_parent ( context . gc_context , Some ( self . into ( ) ) ) ; child . post_instantiation ( context , None , Instantiator :: Movie , false ) ; child . construct_frame ( context ) ; child . set_parent ( context . gc_context , Some ( state_sprite . into ( ) ) ) ; } ( state_sprite . into ( ) , true ) } }
Construct a given state of the button and return it's containing
DisplayObject.
Construct a given state of the button and return it ' s containing DisplayObject .
self
context
&mut UpdateContext<'_, 'gc, '_>
swf_state
swf::ButtonState