Represents a layer on a timeline.
예제 #1
0
 /// <summary>
 /// Initializes a new instance of the PlaceObject class as a display
 /// list instruction to put an item onto the stage.
 /// </summary>
 public PlaceObject(
     ICharacter character,
     Layer layer,
     int? clipDepth,
     Matrix matrix,
     string name,
     bool isMove,
     ColorTransform cxform,
     string className,
     int? ratio)
 {
     this.Character = character;
     this.ClipDepth = clipDepth;
     this.Matrix = matrix;
     this.Name = name;
     this.IsMove = isMove;
     this.CXForm = cxform;
     this.Layer = layer;
     this.ClassName = className;
     this.Ratio = ratio;
 }
예제 #2
0
        public void Instantiate(int frameNum, Sprite sprite, Layer.Position layering, Matrix position, string instanceName, string qClassName)
        {
            AS3Class instanceClass = sprite.Class;

            if (this.Class == null)
            {
                throw new SWFModellerException(
                        SWFModellerError.Internal,
                        "Can't instantiate " + instanceName + " on timeline with no code");
            }

            DoABC scriptTag = this.Root.FirstScript;
            if (scriptTag == null)
            {
                /* ISSUE 70: Y'know, we can generate scripts. We should probably do that. */
                throw new SWFModellerException(
                        SWFModellerError.Internal,
                        "Can't instantiate clips in a SWF with no code.");
            }

            if (instanceClass == null)
            {
                DoABC.GenerateDefaultScript(qClassName, sprite);
                instanceClass = sprite.Class;
            }

            /* Create instance variable of type referenced by instanceClass */

            Namespace propNS = scriptTag.Code.CreateNamespace(Namespace.NamespaceKind.Package, string.Empty);
            Multiname propName = scriptTag.Code.CreateMultiname(Multiname.MultinameKind.QName, instanceName, propNS, NamespaceSet.EmptySet);

            if (this.Class is AS3ClassDef)
            {
                ((AS3ClassDef)this.Class).AddInstanceTrait(new SlotTrait()
                {
                    Kind = TraitKind.Slot,
                    TypeName = instanceClass.Name,
                    Name = propName,
                    ValKind = ConstantKind.ConUndefined
                });
            }

            this.GetFrame(frameNum).AddTag(new PlaceObject(sprite, this.GetFreeLayer(layering), null, position, instanceName, false, null, null, null));
        }
예제 #3
0
        public int GetLayerIndex(Layer layer)
        {
            int idx = -1;

            if (this.LayerList != null)
            {
                idx = this.LayerList.FindIndex(l => l == layer);
            }

            if (idx == -1)
            {
                throw new SWFModellerException(
                        SWFModellerError.Timeline,
                        "Layer does not belong on this timeline");
            }

            return idx + 1;
        }
예제 #4
0
        public Layer GetFreeLayer(Layer.Position position)
        {
            switch (position)
            {
                case Layer.Position.Front:
                    Layer l = new Layer(this);
                    this.LayerList.Add(l);
                    return l;

                case Layer.Position.Back:
                default:
                    throw new SWFModellerException(
                            SWFModellerError.Internal,
                            "SWF::GetFreeLayer; " + position.ToString());
            }
        }
예제 #5
0
        public IDisplayListItem Clone(Layer l, bool rename)
        {
            /* ISSUE 19: Can't decide if we want to clone the characters, or clone them if we
             * pass in a flag and leave it to the swiffotron's logic to decide. */

            string name = this.Name;
            if (rename && name != null)
            {
                name += "_copy";
            }

            PlaceObject po = new PlaceObject(
                    this.Character,
                    l,
                    this.ClipDepth,
                    this.Matrix == null ? null : this.Matrix.Copy(),
                    name,
                    this.IsMove,
                    this.CXForm == null ? null : this.CXForm.Clone(),
                    this.ClassName,
                    this.Ratio);

            /* ISSUE 19: Check that the name doesn't exist on the target layer's timeline. Remember the target
             * timeline might be different to the source timeline, so name collisions may or may not happen.
             * you might think passing in 'rename == true' all the time would be a good thing, but actually
             * this just breaks all the bytecode. I'm not entirely sure it's possible to fix that.
             * Best advice.. be careful with your names.
             */

            return po;
        }
예제 #6
0
        /// <summary>
        /// Initializes a new instance of a sprite by cloning another timeline.
        /// </summary>
        /// <param name="srcTimeline">The timeline to clone.</param>
        /// <param name="className">If the cloned timeline is a SWF, then
        /// you should pass in a class name here. The MainTimeline class
        /// will be renamed in here to this new name.</param>
        public Sprite(Timeline srcTimeline, SWF root, string className = null)
        {
            this._root = root;

            /* Layers are just objects that exist purely to be arranged in some
             * kind of order and be pointed at by more meaningful, other things.
             * To clone layers, we need to simply copy the list and map old
             * layer refs to our new ones. */
            Dictionary<Layer, Layer> newLayers = new Dictionary<Layer, Layer>(srcTimeline.LayerCount);
            foreach (Layer l in srcTimeline.Layers)
            {
                Layer newLayer = new Layer(this);
                LayerList.Add(newLayer);
                newLayers.Add(l, newLayer);
            }

            FrameList = new List<Frame>((int)srcTimeline.FrameCount);
            foreach (Frame f in srcTimeline.Frames)
            {
                Frame newFrame = new Frame();
                foreach (IDisplayListItem dli in f.DisplayList)
                {
                    newFrame.AddTag(dli.Clone(newLayers[dli.Layer], false));
                }
                FrameList.Add(newFrame);
            }

            if (srcTimeline is SWF)
            {
                SWF srcSWF = (SWF)srcTimeline;

                if (className != null)
                {
                    if (srcSWF.Class != null)
                    {
                        srcSWF.RenameMainTimelineClass(className);
                    }
                    /* Else the class will be generated later */
                }

                RemapFonts(srcSWF, root);

                if (className != null)
                {
                    foreach (DoABC abc in srcSWF.Scripts)
                    {
                        root.MergeScript(abc);
                    }
                }

                if (className == null)
                {
                    /* It's tempting to use ClassByName("flash.display.MovieClip") but
                     * remember that that class exists in the player, not the SWF. What
                     * we need in this case is just the name of the class, not a reference
                     * to the class itself. Because that's complicated, we assign a
                     * dummy class and watch for it when we write the class out. */
                    this.Class = AdobeClass.CreateFlashDisplayMovieClip(root.FirstScript.Code);
                }
                else
                {
                    this.Class = srcSWF.Class;
                }
            }
        }