Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

button.cc

Go to the documentation of this file.
00001 
00002 // Flash Plugin and Player
00003 // Copyright (C) 1998 Olivier Debon
00004 // 
00005 // This program is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU General Public License
00007 // as published by the Free Software Foundation; either version 2
00008 // of the License, or (at your option) any later version.
00009 // 
00010 // This program is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 // 
00015 // You should have received a copy of the GNU General Public License
00016 // along with this program; if not, write to the Free Software
00017 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00018 // 
00020 //  Author : Olivier Debon  <odebon@club-internet.fr>
00021 //  
00022 
00023 #include "swf.h"
00024 
00025 #ifdef RCSID
00026 static char *rcsid = "$Id: button.cc,v 1.1.1.1 2002/01/25 22:14:58 kergoth Exp $";
00027 #endif
00028 
00029 #define PRINT 0
00030 
00031 // Contructor
00032 
00033 Button::Button(long id, int level) : Character(ButtonType, id)
00034 {
00035         defLevel = level;
00036         actionRecords = 0;
00037         buttonRecords = 0;
00038         conditionList = 0;
00039         reset();
00040         isMenu = 0;
00041         sound[0] = sound[1] = sound[2] = sound[3] = 0;
00042 }
00043 
00044 // Destructor
00045 
00046 Button::~Button()
00047 {
00048         if (actionRecords) {
00049                 ActionRecord *ar,*del;
00050                 for(ar = actionRecords; ar;) {
00051                         del = ar;
00052                         ar = ar->next;
00053                         delete del;
00054                 }
00055         }
00056         if (buttonRecords) {
00057                 ButtonRecord *br,*del;
00058                 for(br = buttonRecords; br;) {
00059                         del = br;
00060                         br = br->next;
00061                         if (del->cxform)
00062                                 delete del->cxform;
00063                         delete del;
00064                 }
00065         }
00066         if (conditionList) {
00067                 Condition *cond,*del;
00068                 for(cond = conditionList; cond;) {
00069                         ActionRecord *ar,*d;
00070 
00071                         for(ar = cond->actions; ar;) {
00072                                 d = ar;
00073                                 ar = ar->next;
00074                                 delete d;
00075                         }
00076 
00077                         del = cond;
00078                         cond = cond->next;
00079                         delete del;
00080                 }
00081         }
00082 }
00083 
00084 ButtonRecord *
00085 Button::getButtonRecords()
00086 {
00087         return buttonRecords;
00088 }
00089 
00090 ActionRecord *
00091 Button::getActionRecords()
00092 {
00093         return actionRecords;
00094 }
00095 
00096 Sound **
00097 Button::getSounds()
00098 {
00099         return sound;
00100 }
00101 
00102 Condition *
00103 Button::getConditionList()
00104 {
00105         return conditionList;
00106 }
00107 
00108 void
00109 Button::setButtonSound(Sound *s, int state)
00110 {
00111         if (state >=0 && state < 4) {
00112                 sound[state] = s;
00113         }
00114 }
00115 
00116 void
00117 Button::setButtonMenu(int menu)
00118 {
00119         isMenu = menu;
00120 }
00121 
00122 void
00123 Button::addButtonRecord( ButtonRecord *br )
00124 {
00125 #if 0
00126     /* SURTOUT PAS !!! */
00127     ButtonRecord **l;
00128     
00129     /* sort by layer */
00130     l=&buttonRecords;
00131     while (*l != NULL && (*l)->layer < br->layer) l = &(*l)->next;
00132     br->next = *l;
00133     *l = br;
00134 #else
00135         br->next = 0;
00136 
00137         if (buttonRecords == 0) {
00138                 buttonRecords = br;
00139         } else {
00140                 ButtonRecord *current;
00141 
00142                 for(current = buttonRecords; current->next; current = current->next);
00143 
00144                 current->next = br;
00145         }
00146 #endif
00147 }
00148 
00149 void
00150 Button::addCondition( long transition )
00151 {
00152         Condition *condition;
00153 
00154         condition = new Condition;
00155         if (condition == NULL) return;
00156 
00157         condition->transition = transition; 
00158         condition->next = conditionList;
00159 
00160         // Move current actionRecords to this condition
00161         condition->actions = actionRecords;
00162         actionRecords = 0;
00163 
00164         conditionList = condition;
00165 }
00166 
00167 void
00168 Button::addActionRecord( ActionRecord *ar )
00169 {
00170         ar->next = 0;
00171 
00172         if (actionRecords == 0) {
00173                 actionRecords = ar;
00174         } else {
00175                 ActionRecord *current;
00176 
00177                 for(current = actionRecords; current->next; current = current->next);
00178 
00179                 current->next = ar;
00180         }
00181 }
00182 
00183 void
00184 Button::getRegion(GraphicDevice *gd, Matrix *matrix, void *id, ScanLineFunc scan_line_func)
00185 {
00186         ButtonRecord *br;
00187 
00188         for (br = buttonRecords; br; br = br->next)
00189         {
00190                 if ((br->state & stateHitTest) && br->character /* Temporaire */) {
00191                         Matrix mat;
00192 
00193                         mat = (*matrix) * br->buttonMatrix;
00194                         br->character->getRegion(gd, &mat, id, scan_line_func);
00195                 }
00196         }
00197 }
00198 
00199 int
00200 Button::execute(GraphicDevice *gd, Matrix *matrix, Cxform *cxform, ButtonState renderState)
00201 {
00202         ButtonRecord *br;
00203         int sprite = 0;
00204         Cxform *cxf = 0;
00205 
00206 #if PRINT==2
00207         printf("Rendering Button %d  for State(s) ", getTagId());
00208 #endif
00209         for (br = buttonRecords; br; br = br->next)
00210         {
00211             if ((br->state & renderState) && br->character != NULL) {
00212                         Matrix mat;
00213                         
00214 #if PRINT==2
00215                 printf("%d ", br->state);
00216 #endif
00217                         mat = (*matrix) * br->buttonMatrix;
00218 
00219                         if (cxform) {
00220                                 cxf = cxform;
00221                         } else if (br->cxform) {
00222                                 cxf = br->cxform;
00223                         } 
00224 
00225                         if (br->character->execute(gd, &mat, cxf)) {
00226                                 sprite = 1;
00227                         }
00228                 }
00229         }
00230 #if PRINT==2
00231         printf("\n");
00232 #endif
00233         return sprite;
00234 }
00235 
00236 ActionRecord *
00237 Button::getActionFromTransition(ButtonState cur, ButtonState old)
00238 {
00239         Condition *cond;
00240         long mask;
00241 
00242         if (old == cur) return NULL;
00243 
00244         /* transitions */
00245         mask = 0;
00246         if (old == stateUp && cur == stateOver)
00247             mask |= 0x001;
00248         else if (old == stateOver && cur == stateUp)
00249             mask |= 0x002;
00250         else if (old == stateOver && cur == stateDown)
00251             mask |= 0x004;
00252         else if (old == stateDown && cur == stateOver)
00253             mask |= 0x008;
00254 
00255         if (!isMenu) {
00256             /* push button transitions (XXX: not quite correct) */
00257             if (old == stateDown && cur == stateUp)
00258                 mask = 0x010;
00259             else if (old == stateUp && cur == stateDown)
00260                 mask = 0x020;
00261             /* XXX: what is transition 0x040 ?? */
00262         } else {
00263             /* menu button transitions (XXX: not quite correct) */
00264             if (old == stateUp && cur == stateDown)
00265                 mask = 0x080;
00266             else if (old == stateDown && cur == stateUp)
00267                 mask = 0x100;
00268         }
00269 
00270         for (cond = conditionList; cond; cond = cond->next) {
00271                 if (cond->transition & mask) {
00272                         return cond->actions;
00273                 }
00274         }
00275         return 0;
00276 }
00277 
00278 void
00279 Button::getBoundingBox(Rect *bbox, DisplayListEntry *e)
00280 {
00281         ButtonRecord *br;
00282 
00283         bbox->reset();
00284         for (br = buttonRecords; br; br = br->next)
00285         {
00286                 if (br->state & e->renderState) {
00287                         if (br->character) {
00288                                 Rect bb;
00289                                 
00290                                 bb.reset();
00291                                 br->character->getBoundingBox(&bb,e);
00292                                 transformBoundingBox(bbox, &br->buttonMatrix, &bb, 0);
00293                         }
00294                 }
00295         }
00296 }
00297 
00298 /* Get current render character, actually it should be a list of characters
00299    so a DisplayList after all */
00300 Character *
00301 Button::getRenderCharacter(ButtonState state)
00302 {
00303         ButtonRecord *br;
00304 
00305         for (br = buttonRecords; br; br = br->next)
00306         {
00307                 if (br->state & state) {
00308                         return br->character;
00309                 }
00310         }
00311         return 0;
00312 }
00313 
00314 void
00315 Button::updateButtonState(DisplayListEntry *e)
00316 {
00317         ButtonRecord *br;
00318 
00319         e->buttonCharacter = 0;
00320         for (br = buttonRecords; br; br = br->next)
00321         {
00322                 if (br->state & e->renderState) {
00323                         e->buttonCharacter = br->character;
00324                         e->buttonMatrix = br->buttonMatrix;
00325                         return;
00326                 }
00327         }
00328 }

Generated on Sat Nov 5 16:15:34 2005 for OPIE by  doxygen 1.4.2