예제 #1
0
SObject* DisplayList::MoveObject(SObject* parent, PlaceInfo* info)
{
	// See if there is already an object at this depth or find the insertion point
	SObject* obj = parent->bottomChild;
	while ( obj ) {
	 	if ( obj->depth >= info->depth ) 
			break;
		obj = obj->above;
	}

	if ( obj ) {
		// We found an object at this depth
		if ( obj->depth != info->depth ) {
			FLASHASSERT(false);
			return 0;		// don't move the wrong object
		}

        if (obj->puppet)
            return 0;       // don't move the object if it's puppeted

		// Move the proper fields of the object
		obj->Modify();
		if ( info->flags & splaceCharacter ) {
			// The type of sprite or button objects must never change
			if ( obj->character->type != info->character->type && 
				 (obj->character->type == spriteChar || info->character->type == spriteChar ||
				  obj->character->type == buttonChar || info->character->type == buttonChar) ) {
				FLASHASSERT(false);		// this should never happen, there was a beta build where we did export like this, so prevent the crash
			} else {
				obj->character = info->character;
			}
		}
		if ( info->flags & splaceMatrix )
			obj->xform.mat = info->mat;
		if ( info->flags & splaceColorTransform )
			obj->xform.cxform = info->cxform;
		if ( info->flags & splaceRatio )
			obj->ratio = info->ratio;
	}
	return obj;
}
예제 #2
0
void DisplayList::FinishHold()
// Compare the old and the new list
// If an old object matches a new object, replace the new object with the old object
{
	FLASHASSERT(holdParent);

	SObject** oldLink = &holdList;
	SObject** newLink = &holdParent->bottomChild;

    for (;;) {
		SObject* oldObj = *oldLink;
		SObject* newObj = *newLink;

		if ( !oldObj )
			break;	// we are done

		if ( !newObj || oldObj->depth < newObj->depth ) {
			if ( oldObj->depth >= 0x4000 ) {
				// This is a cloned object, it always gets copied to the new list
				FLASHASSERT(!newObj);	// none of the new obj's should have a depth > 4000
				*oldLink = oldObj->above;	// remove from old list
				oldObj->above = *newLink;	// place on new list
				*newLink = oldObj;

			} else {
				// Get rid of the old object
				DoRemove(oldLink);
			}

		} else if ( oldObj->depth == newObj->depth ) {
			// Compare these objects
            BOOL remove = true;
			if (oldObj->character == newObj->character && oldObj->ratio == newObj->ratio && oldObj->clipDepth == newObj->clipDepth) 
            {
				// Check the matrix and cxform and ratio
				BOOL moved = !Equal(&oldObj->xform, &newObj->xform);
				if (!moved || oldObj->character->type == spriteChar) 
                {
					if ( moved && !oldObj->puppet) 
                    {
						oldObj->Modify();
						oldObj->xform = newObj->xform;
						//oldObj->ratio = newObj->ratio;
					}

					if ( button == newObj ) 
                    { 
						FLASHASSERT(oldObj->state == buttonState);
						button = oldObj;
						//UpdateButton(obj, state);
					}
                    remove = false;
				}
			}
            else if (
                oldObj->ratio == newObj->ratio && 
                (oldObj->character->type == spriteExternalChar || oldObj->character->type == spriteChar) && 
                (newObj->character->type == spriteChar || newObj->character->type == spriteExternalChar))
            {
                // we are dealing with externally loaded sprite
                // or an empty placeholder. It inherits the 
                // sprite ratio of the sprite we are replacing. 
                // This means that it goes away when the same 
                // time the replaced sprite should have gone away
				
                if (!Equal(&oldObj->xform, &newObj->xform))
                {
                        if (!oldObj->puppet)
                        {
						    oldObj->Modify();
						    oldObj->xform = newObj->xform;
                        }
			    }
                remove = false;
            }
            
            if (!remove)
            {
				DoRemove(newLink);			// delete the new obj
				*oldLink = oldObj->above;	// remove from old list
				oldObj->above = *newLink;	// place on new list
				*newLink = oldObj;
				continue;
            }
			
			newLink = &newObj->above;
			DoRemove(oldLink);

		} else {
			// Just look at the next new object
			FLASHASSERT(oldObj->depth > newObj->depth);
			newLink = &newObj->above;
		}
	}

#ifdef EDITTEXT
	// Update edit texts on hold list
	SObject* obj = holdParent->bottomChild;
	while (obj) {
		if (obj->character && obj->character->type == editTextChar) {
			obj->editText->UpdateFromVariable();
		}
		obj = obj->above;
	}
#endif

    holdParent = 0;
}
예제 #3
0
SObject* DisplayList::PlaceObject(SObject* parent, PlaceInfo* info)
{
	// Find the insertion point
	SObject** link = &parent->bottomChild;
	for (;;) {
		SObject* obj = *link;
		if ( !obj ) break;
	 	if ( obj->depth >= info->depth ) {
			FLASHASSERT(obj->depth != info->depth);
			break;
		}
		link = &obj->above;
	}

	// Create a new object
	SObject* obj = CreateObject();
	if ( !obj ) return 0;

	// Add to list
	obj->parent = parent;
	obj->above = *link;
	*link = obj;

	// Set up object
	obj->character = info->character;
	obj->xform = *info;
	obj->depth = info->depth;
	obj->ratio = info->ratio;
    obj->puppet = info->puppet;
	obj->drawn = false;
    obj->visible = true;
	obj->dragCenter = false;
	RectSetEmpty(&obj->dragConstraint);
	obj->dropTarget = NULL;
	obj->display = this;
	obj->bottomChild = 0;
	obj->edges = 0;
	obj->colors = 0;
	obj->state = 0;
#ifdef EDITTEXT
	obj->editText = 0;
#endif

	// If this is a movie clip and it has no name,
	// generate a default name
	if (obj->character->type == spriteChar && !info->name) {
		URLBuilder ub;
		ub.AppendString("instance");
		ub.AppendInt(++instanceNameCount);
		obj->name = CreateStr(ub.buf);
	} else {
		// Regular processing: copy name if present
		obj->name = CreateStr(info->name);
	}
	obj->thread = parent ? parent->thread : 0;
	obj->clipDepth = info->flags & splaceDefineClip ? info->clipDepth : 0;//(info->flags & splaceDefineClip) != 0;
	obj->Modify();

	switch ( obj->character->type ) {
		case buttonChar: {
			// Set up the button state
			int state = bsIdle;
			if ( obj->depth == buttonDepth && obj->parent == buttonParent && 
				 buttonCharacter == obj->character && obj->ratio == buttonRatio ) {
				// The button is currently being tracked
				FLASHASSERT(obj->character->type == buttonChar);
				button = obj;
				state = buttonState;
			}
			UpdateButton(obj, state);
		} break;

#ifdef EDITTEXT
		case editTextChar:
			{
				obj->editText = new EditText(obj);
				if (holdParent != obj->parent) {
					// Not doing a hold... update value immediately
					obj->editText->UpdateFromVariable();
				}
				// If there is a holdParent, the edit text's value will
				// be updated later.
			}
			break;
#endif

		case spriteExternalChar:
        {
			ScriptThread    *thread = 0;
            ScriptPlayer    *player = obj->character->player;
            int             startPos = 0;
            int             len = 0;
            int             numFrames = 0;

            if (info->flags & splaceCloneExternalSprite)
            {
                // means we are cloning an existing
                // external sprite
                if (player->len >= player->scriptLen)
                {
                    // we only clone the external
                    // sprite if it has been completely loaded
                    // allocate full player instead of thread
                    // it is easier to delete the external
                    // sprite if it has its own player
                    thread = new ScriptPlayer;
                    startPos = player->startPos;
                    len = player->len;
                    numFrames = player->numFrames;
                    thread->script = player->script;
                    ((ScriptPlayer *) thread)->numFramesComplete = player->numFramesComplete;
                    player = (ScriptPlayer *) thread;
                    player->gotHeader = true;
                    
                    // add a ref count to the script
                    // we don't want to duplicate it
                    // so we want to make sure it's
                    // protected from deletion for
                    // cloned external sprites
                    player->scriptRefCount = obj->character->player->scriptRefCount;
                    player->ScriptAddRefCount();
                }
            }
            else
            {
                // note that it's ok to have some of the
                // initial values of the len, etc. set
                // to zero. they will be set during pushdata
                thread = player;

                // add a ref count to the script
                // we don't want to duplicate it
                // so we want to make sure it's
                // protected from deletion for
                // cloned external sprites
                player->ScriptAddRefCount();
            }
			
            if ( thread ) 
            {
				thread->ClearState();
				obj->thread = thread;
				thread->player = player;
				thread->layerDepth = obj->depth;
				thread->rootObject = obj;
				thread->SetDisplay(obj->display);
				thread->Attach(obj->character->player->script, startPos);
				thread->len = len;
				thread->startPos = startPos;
				thread->numFrames = numFrames;
                
                // for non cloned sprite this won't draw the frame
                // untill we push data into the script (this is ok)
				thread->DrawFrame(0, false);
			}
		} break;

  		case spriteChar: {
			// Create a sprite thread
			ScriptThread* thread = new ScriptThread();
			if ( thread ) {
				thread->ClearState();
				obj->thread = thread;
				thread->player = obj->character->player;
				thread->layerDepth = obj->depth;
				thread->rootObject = obj;
				thread->SetDisplay(obj->display);
				thread->Attach(obj->character->data, 0);
				thread->len = obj->character->sprite.length;
				thread->startPos = 0;
				thread->numFrames = obj->character->sprite.numFrames;
				thread->DrawFrame(0, false);
			}
		} break;
	}

	return obj;
}