home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus Leser 19 / Amiga Plus Leser CD 19.iso / Tools / Freeware / Swf_Player / Lib / button.cc < prev    next >
Encoding:
C/C++ Source or Header  |  2002-11-17  |  6.5 KB  |  329 lines

  1. /////////////////////////////////////////////////////////////
  2. // Flash Plugin and Player
  3. // Copyright (C) 1998 Olivier Debon
  4. // 
  5. // This program is free software; you can redistribute it and/or
  6. // modify it under the terms of the GNU General Public License
  7. // as published by the Free Software Foundation; either version 2
  8. // of the License, or (at your option) any later version.
  9. // 
  10. // This program is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. // GNU General Public License for more details.
  14. // 
  15. // You should have received a copy of the GNU General Public License
  16. // along with this program; if not, write to the Free Software
  17. // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18. // 
  19. ///////////////////////////////////////////////////////////////
  20. //  Author : Olivier Debon  <odebon@club-internet.fr>
  21. //  
  22.  
  23. #include "swf.h"
  24.  
  25. #ifdef RCSID
  26. static char *rcsid = "$Id: button.cc,v 1.5 1999/09/08 10:59:29 ode Exp $";
  27. #endif
  28.  
  29. #define PRINT 0
  30.  
  31. // Contructor
  32.  
  33. Button::Button(long id, int level) : Character(ButtonType, id)
  34. {
  35.     defLevel = level;
  36.     actionRecords = 0;
  37.     buttonRecords = 0;
  38.     conditionList = 0;
  39.     reset();
  40.     isMenu = 0;
  41.     sound[0] = sound[1] = sound[2] = sound[3] = 0;
  42. }
  43.  
  44. // Destructor
  45.  
  46. Button::~Button()
  47. {
  48.     if (actionRecords) {
  49.         ActionRecord *ar,*del;
  50.         for(ar = actionRecords; ar;) {
  51.             del = ar;
  52.             ar = ar->next;
  53.             delete del;
  54.         }
  55.     }
  56.     if (buttonRecords) {
  57.         ButtonRecord *br,*del;
  58.         for(br = buttonRecords; br;) {
  59.             del = br;
  60.             br = br->next;
  61.             if (del->cxform)
  62.                 delete del->cxform;
  63.             delete del;
  64.         }
  65.     }
  66.     if (conditionList) {
  67.         Condition *cond,*del;
  68.         for(cond = conditionList; cond;) {
  69.             ActionRecord *ar,*d;
  70.  
  71.             for(ar = cond->actions; ar;) {
  72.                 d = ar;
  73.                 ar = ar->next;
  74.                 delete d;
  75.             }
  76.  
  77.             del = cond;
  78.             cond = cond->next;
  79.             delete del;
  80.         }
  81.     }
  82. }
  83.  
  84. ButtonRecord *
  85. Button::getButtonRecords()
  86. {
  87.     return buttonRecords;
  88. }
  89.  
  90. ActionRecord *
  91. Button::getActionRecords()
  92. {
  93.     return actionRecords;
  94. }
  95.  
  96. Sound **
  97. Button::getSounds()
  98. {
  99.     return sound;
  100. }
  101.  
  102. Condition *
  103. Button::getConditionList()
  104. {
  105.     return conditionList;
  106. }
  107.  
  108. void
  109. Button::setButtonSound(Sound *s, int state)
  110. {
  111.     if (state >=0 && state < 4) {
  112.         sound[state] = s;
  113.     }
  114. }
  115.  
  116. void
  117. Button::setButtonMenu(int menu)
  118. {
  119.     isMenu = menu;
  120. }
  121.  
  122. void
  123. Button::addButtonRecord( ButtonRecord *br )
  124. {
  125. #if 0
  126.     /* SURTOUT PAS !!! */
  127.     ButtonRecord **l;
  128.     
  129.     /* sort by layer */
  130.     l=&buttonRecords;
  131.     while (*l != NULL && (*l)->layer < br->layer) l = &(*l)->next;
  132.     br->next = *l;
  133.     *l = br;
  134. #else
  135.     br->next = 0;
  136.  
  137.     if (buttonRecords == 0) {
  138.         buttonRecords = br;
  139.     } else {
  140.         ButtonRecord *current;
  141.  
  142.         for(current = buttonRecords; current->next; current = current->next);
  143.  
  144.         current->next = br;
  145.     }
  146. #endif
  147. }
  148.  
  149. void
  150. Button::addCondition( long transition )
  151. {
  152.     Condition *condition;
  153.  
  154.     condition = new Condition;
  155.     if (condition == NULL) return;
  156.  
  157.     condition->transition = transition; 
  158.     condition->next = conditionList;
  159.  
  160.     // Move current actionRecords to this condition
  161.     condition->actions = actionRecords;
  162.     actionRecords = 0;
  163.  
  164.     conditionList = condition;
  165. }
  166.  
  167. void
  168. Button::addActionRecord( ActionRecord *ar )
  169. {
  170.     ar->next = 0;
  171.  
  172.     if (actionRecords == 0) {
  173.         actionRecords = ar;
  174.     } else {
  175.         ActionRecord *current;
  176.  
  177.         for(current = actionRecords; current->next; current = current->next);
  178.  
  179.         current->next = ar;
  180.     }
  181. }
  182.  
  183. void
  184. Button::getRegion(GraphicDevice *gd, Matrix *matrix, void *id, ScanLineFunc scan_line_func)
  185. {
  186.     ButtonRecord *br;
  187.  
  188.     for (br = buttonRecords; br; br = br->next)
  189.     {
  190.         if ((br->state & stateHitTest) && br->character /* Temporaire */) {
  191.             Matrix mat;
  192.  
  193.             mat = (*matrix) * br->buttonMatrix;
  194.             br->character->getRegion(gd, &mat, id, scan_line_func);
  195.         }
  196.     }
  197. }
  198.  
  199. int
  200. Button::execute(GraphicDevice *gd, Matrix *matrix, Cxform *cxform, ButtonState renderState)
  201. {
  202.     ButtonRecord *br;
  203.     int sprite = 0;
  204.     Cxform *cxf = 0;
  205.  
  206. #if PRINT==2
  207.     printf("Rendering Button %d  for State(s) ", getTagId());
  208. #endif
  209.     for (br = buttonRecords; br; br = br->next)
  210.     {
  211.             if ((br->state & renderState) && br->character != NULL) {
  212.             Matrix mat;
  213.             
  214. #if PRINT==2
  215.         printf("%d ", br->state);
  216. #endif
  217.             mat = (*matrix) * br->buttonMatrix;
  218.  
  219.                         if (cxform) {
  220.                 cxf = cxform;
  221.             } else if (br->cxform) {
  222.                 cxf = br->cxform;
  223.             } 
  224.  
  225.             if (br->character->execute(gd, &mat, cxf)) {
  226.                 sprite = 1;
  227.             }
  228.         }
  229.     }
  230. #if PRINT==2
  231.     printf("\n");
  232. #endif
  233.     return sprite;
  234. }
  235.  
  236. ActionRecord *
  237. Button::getActionFromTransition(ButtonState cur, ButtonState old)
  238. {
  239.     Condition *cond;
  240.     long mask;
  241.  
  242.     if (old == cur) return NULL;
  243.  
  244.         /* transitions */
  245.         mask = 0;
  246.         if (old == stateUp && cur == stateOver)
  247.             mask |= 0x001;
  248.         else if (old == stateOver && cur == stateUp)
  249.             mask |= 0x002;
  250.         else if (old == stateOver && cur == stateDown)
  251.             mask |= 0x004;
  252.         else if (old == stateDown && cur == stateOver)
  253.             mask |= 0x008;
  254.  
  255.         if (!isMenu) {
  256.             /* push button transitions (XXX: not quite correct) */
  257.             if (old == stateDown && cur == stateUp)
  258.                 mask = 0x010;
  259.             else if (old == stateUp && cur == stateDown)
  260.                 mask = 0x020;
  261.             /* XXX: what is transition 0x040 ?? */
  262.         } else {
  263.             /* menu button transitions (XXX: not quite correct) */
  264.             if (old == stateUp && cur == stateDown)
  265.                 mask = 0x080;
  266.             else if (old == stateDown && cur == stateUp)
  267.                 mask = 0x100;
  268.         }
  269.  
  270.     for (cond = conditionList; cond; cond = cond->next) {
  271.         if (cond->transition & mask) {
  272.             return cond->actions;
  273.         }
  274.     }
  275.     return 0;
  276. }
  277.  
  278. void
  279. Button::getBoundingBox(Rect *bbox, DisplayListEntry *e)
  280. {
  281.     ButtonRecord *br;
  282.  
  283.     bbox->reset();
  284.     for (br = buttonRecords; br; br = br->next)
  285.     {
  286.                 if (br->state & e->renderState) {
  287.             if (br->character) {
  288.                 Rect bb;
  289.                 
  290.                 bb.reset();
  291.                 br->character->getBoundingBox(&bb,e);
  292.                 transformBoundingBox(bbox, &br->buttonMatrix, &bb, 0);
  293.             }
  294.         }
  295.     }
  296. }
  297.  
  298. /* Get current render character, actually it should be a list of characters
  299.    so a DisplayList after all */
  300. Character *
  301. Button::getRenderCharacter(ButtonState state)
  302. {
  303.     ButtonRecord *br;
  304.  
  305.     for (br = buttonRecords; br; br = br->next)
  306.     {
  307.                 if (br->state & state) {
  308.             return br->character;
  309.         }
  310.     }
  311.     return 0;
  312. }
  313.  
  314. void
  315. Button::updateButtonState(DisplayListEntry *e)
  316. {
  317.     ButtonRecord *br;
  318.  
  319.     e->buttonCharacter = 0;
  320.     for (br = buttonRecords; br; br = br->next)
  321.     {
  322.                 if (br->state & e->renderState) {
  323.             e->buttonCharacter = br->character;
  324.             e->buttonMatrix = br->buttonMatrix;
  325.             return;
  326.         }
  327.     }
  328. }
  329.