?? displaylist.cpp
字號:
////////////////////////////////////////////////////////////
// Flash Plugin and Player
// Copyright (C) 1998,1999 Olivier Debon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////
// Author : Olivier Debon <odebon@club-internet.fr>
//
#include "swf.h"
#ifdef RCSID
static char *rcsid = "$Id: displaylist.cc,v 1.4 1999/09/03 15:17:40 ode Exp $";
#endif
#define PRINT 0
void deleteButton(FlashMovie *movie, DisplayListEntry *e)
{
/* save the focus */
if (movie->mouse_active == 0 && e->renderState == stateOver) {
movie->lost_over = (Button *)e->character;
movie->cur_focus = NULL;
}
if (e == movie->cur_focus) {
movie->cur_focus = NULL;
}
}
void addButton(FlashMovie *movie, DisplayListEntry *e)
{
if (movie->mouse_active == 0 &&
movie->cur_focus == NULL &&
movie->lost_over == (Button *)e->character) {
/* restore the lost focus */
e->renderState = stateOver;
e->oldState = stateOver;
((Button *)e->character)->updateButtonState(e);
movie->lost_over = NULL;
movie->cur_focus = e;
}
}
DisplayList::DisplayList(FlashMovie *movie)
{
list = NULL;
this->movie = movie;
bbox.reset();
isSprite = 0;
}
DisplayList::~DisplayList()
{
clearList();
}
void
DisplayList::clearList()
{
DisplayListEntry *del, *e;
for(e = list; e;)
{
updateBoundingBox(e);
if (e->character->isButton()) {
deleteButton(movie,e);
}
del = e;
e = e->next;
delete del;
}
list = 0;
}
DisplayListEntry *
DisplayList::getList()
{
return list;
}
static void bbox(Rect *rect, Matrix *m, long x1, long y1)
{
long x,y;
x = m->getX(x1,y1);
y = m->getY(x1,y1);
if (x < rect->xmin) rect->xmin = x;
if (x > rect->xmax) rect->xmax = x;
if (y < rect->ymin) rect->ymin = y;
if (y > rect->ymax) rect->ymax = y;
}
// Update bb to include boundary, optional reset of bb
void transformBoundingBox(Rect *bb, Matrix *matrix, Rect *boundary, int reset)
{
if (reset) {
bb->reset();
}
if (boundary->xmin != LONG_MAX) {
bbox(bb, matrix, boundary->xmin, boundary->ymin);
bbox(bb, matrix, boundary->xmax, boundary->ymin);
bbox(bb, matrix, boundary->xmin, boundary->ymax);
bbox(bb, matrix, boundary->xmax, boundary->ymax);
}
}
void
DisplayList::placeObject(GraphicDevice *gd,Character *character, long depth, Matrix *matrix, Cxform *cxform, char *name)
{
DisplayListEntry *n,*e,*prev;
n = new DisplayListEntry;
if (n == NULL) return;
n->depth = depth;
n->matrix = matrix;
n->cxform = cxform;
n->character = character;
n->instanceName = name;
n->owner = this;
#if 0
printf("Dl %lx: placeObject: depth=%d character=%d cxform=%p\n",
this, n->depth,n->character ? n->character->getTagId() : 0, cxform);
#endif
if (character == 0 || matrix == 0 || cxform == 0) {
for (e = list; e; prev = e, e = e->next) {
if (e->depth == n->depth) {
if (character == 0) {
n->character = e->character;
}
if (matrix == 0) {
n->matrix = e->matrix;
}
if (cxform == 0) {
n->cxform = e->cxform;
}
break;
}
}
}
if (n->character == 0) {
// Not found !!! Should not happen
// printf("PlaceObject cannot find character at depth %ld\n", n->depth);
delete n;
return;
}
prev = 0;
for (e = list; e; prev = e, e = e->next)
{
if (e->depth == n->depth) {
if (e->character->isButton()) {
deleteButton(movie, e);
}
// Do update, object has moved or been resized
updateBoundingBox(e);
// Replace object
e->depth = n->depth;
e->matrix = n->matrix;
e->cxform = n->cxform;
e->character = n->character;
/* if it is a button, we must update its state */
if (e->character->isButton()) {
movie->buttons_updated = 1;
addButton(movie, e);
}
updateBoundingBox(e);
delete n;
return;
}
if (e->depth > n->depth) break;
}
/* new object */
/* button instantiation */
if (n->character->isButton()) {
n->renderState = stateUp;
n->oldState = stateUp;
((Button *)n->character)->updateButtonState(n);
addButton(movie,n);
}
updateBoundingBox(n);
if (prev == 0) {
// Object comes at first place
n->next = list;
list = n;
} else {
// Insert object
n->next = prev->next;
prev->next = n;
}
}
Character *
DisplayList::removeObject(GraphicDevice *gd,Character *character, long depth)
{
DisplayListEntry *e,*prev;
// List should not be empty
if (list == 0) return 0;
#if 0
printf("removeObject: depth=%d character=%d\n",
depth,character ? character->getTagId() : 0);
#endif
prev = 0;
for (e = list; e; prev = e, e = e->next) {
if (e->depth == depth) {
if (prev) {
prev->next = e->next;
} else {
list = e->next;
}
if (character == 0) {
character = e->character;
}
if (e->character->isButton()) {
deleteButton(movie, e);
}
if (e->character->isSprite()) {
((Sprite*)e->character)->reset();
}
updateBoundingBox(e);
delete e;
return character;
}
}
return 0; // Should not happen
}
void
DisplayList::updateBoundingBox(DisplayListEntry *e)
{
Rect rect;
//rect.reset();
e->character->getBoundingBox(&rect,e);
transformBoundingBox(&this->bbox, e->matrix, &rect, 0);
}
int
DisplayList::updateSprites()
{
Sprite *sprite;
DisplayListEntry *e;
int refresh = 0;
for (e = this->list; e != NULL; e = e->next) {
if (e->character->isButton() && e->buttonCharacter) {
if (e->buttonCharacter->isSprite()) {
Matrix mat;
sprite = (Sprite *)e->buttonCharacter;
refresh |= sprite->program->dl->updateSprites();
refresh |= sprite->program->nestedMovie(this->movie->gd,this->movie->sm, e->matrix, e->cxform);
mat = (*e->matrix) * e->buttonMatrix;
transformBoundingBox(&this->bbox, &mat,
&(sprite->program->dl->bbox),
0);
}
}
if (e->character->isSprite()) {
sprite = (Sprite *)e->character;
refresh |= sprite->program->dl->updateSprites();
refresh |= sprite->program->nestedMovie(this->movie->gd,this->movie->sm, e->matrix, e->cxform);
transformBoundingBox(&this->bbox, e->matrix,
&(sprite->program->dl->bbox),
0);
}
}
return refresh;
}
/* Function can return either 0,1 or 2
0: Nothing match, continue
1: Something matches, but continue searching
2: Something matches, but stop searching
*/
static int exploreButtons1(Program *prg, void *opaque,
ExploreButtonFunc func)
{
DisplayListEntry *e;
int ret, ret2 = 0;
for(e=prg->dl->list; e != NULL; e = e->next) {
if (e->character == NULL) continue;
if (e->character->isButton()) {
ret = func(opaque,prg,e);
if (ret == 2) return ret; // Func asks to return at once !!!
if (ret) ret2 = 1;
}
if (e->character->isSprite()) {
ret = exploreButtons1(((Sprite *)e->character)->program,
opaque,func);
if (ret == 2) return ret; // Func asks to return at once !!!
if (ret) ret2 = 1;
}
}
return ret2;
}
int exploreButtons(FlashMovie *movie, void *opaque, ExploreButtonFunc func)
{
CInputScript *script;
int ret;
script = movie->main;
while (script != NULL) {
if (script->program) {
ret = exploreButtons1(script->program, opaque, func);
if (ret) return ret;
}
script = script->next;
}
return 0;
}
typedef struct {
long x,y;
int hit;
DisplayListEntry *bhit;
} HitTable;
static void button_hit_func(void *id, long y, long start, long end)
{
HitTable *h = (HitTable *) id;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -