Gnash  0.8.10
DefineButtonTag.h
Go to the documentation of this file.
00001 //
00002 //   Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012
00003 //   Free Software Foundation, Inc
00004 //
00005 // This program is free software; you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License as published by
00007 // the Free Software Foundation; either version 3 of the License, or
00008 // (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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00018 //
00019 
00020 #ifndef GNASH_SWF_DEFINEBUTTONTAG_H
00021 #define GNASH_SWF_DEFINEBUTTONTAG_H
00022 
00023 #include <vector>
00024 #include <boost/ptr_container/ptr_vector.hpp>
00025 #include <boost/scoped_ptr.hpp>
00026 #include <boost/cstdint.hpp> 
00027 #include <memory>
00028 
00029 #include "DefinitionTag.h"
00030 #include "SWFMatrix.h" 
00031 #include "SWFCxForm.h" 
00032 #include "action_buffer.h" 
00033 #include "filter_factory.h" 
00034 #include "TypesParser.h"
00035 #include "DefineButtonSoundTag.h"
00036 #include "SWF.h"
00037 #include "Button.h"
00038 
00039 // Forward declarations
00040 namespace gnash {
00041     class movie_definition;
00042     class event_id;
00043     class SWFStream;
00044     class DisplayObject;
00045 }
00046 
00047 namespace gnash {
00048 namespace SWF {
00049 
00050 
00052 class ButtonRecord
00053 {
00054 
00055 public:
00056 
00057     ButtonRecord()
00058         :
00059         _definitionTag(0)
00060     {
00061     }
00062 
00064     //
00069     DisplayObject* instantiate(Button* button, bool name = true) const;
00070 
00072     //
00076     bool hasState(Button::MouseState st) const;
00077 
00079     //
00082     void readRGBTransform(SWFStream& in) {
00083         _cxform = readCxFormRGB(in);
00084     }
00085 
00087     //
00093     bool read(SWFStream& in, TagType t, movie_definition& m,
00094             unsigned long endPos);
00095     
00097     //
00100     bool valid() const {
00101         return (_definitionTag);
00102     }
00103 
00104 private:
00105 
00108     //
00110     Filters _filters;
00111 
00114     //
00116     boost::uint8_t _blendMode;
00117 
00118     bool _hitTest;
00119     bool _down;
00120     bool _over;
00121     bool _up;
00122 
00123     // This is a ref-counted resource, so not owned by anyone.
00124     boost::intrusive_ptr<const DefinitionTag> _definitionTag;
00125 
00126     int _buttonLayer;
00127 
00128     SWFMatrix _matrix;
00129 
00130     SWFCxForm _cxform;
00131 
00132 };
00133     
00135 class ButtonAction
00136 {
00137 public:
00138 
00139     // TODO: define ownership of list elements !!
00140     action_buffer _actions;
00141 
00149     ButtonAction(SWFStream& in, TagType t, unsigned long endPos,
00150             movie_definition& mdef);
00151 
00153     bool triggeredBy(const event_id& ev) const;
00154 
00156     bool triggeredByKeyPress() const {
00157         return (_conditions & KEYPRESS);
00158     }
00159 
00160 private:
00161 
00163     //
00165     int getKeyCode() const {
00166         return (_conditions & KEYPRESS) >> 9;
00167     }
00168 
00169     enum Condition
00170     {
00171         IDLE_TO_OVER_UP = 1 << 0,
00172         OVER_UP_TO_IDLE = 1 << 1,
00173         OVER_UP_TO_OVER_DOWN = 1 << 2,
00174         OVER_DOWN_TO_OVER_UP = 1 << 3,
00175         OVER_DOWN_TO_OUT_DOWN = 1 << 4,
00176         OUT_DOWN_TO_OVER_DOWN = 1 << 5,
00177         OUT_DOWN_TO_IDLE = 1 << 6,
00178         IDLE_TO_OVER_DOWN = 1 << 7,
00179         OVER_DOWN_TO_IDLE = 1 << 8,
00180         KEYPRESS = 0xFE00  // highest 7 bits
00181     };
00182 
00183     boost::uint16_t _conditions;
00184 
00185 };
00186 
00188 class DefineButtonTag : public DefinitionTag
00189 {
00190 public:
00191 
00193     static void loader(SWFStream& in, TagType tag, movie_definition& m, 
00194             const RunResources& r);
00195 
00196     typedef std::vector<ButtonRecord> ButtonRecords; 
00197     typedef boost::ptr_vector<ButtonAction> ButtonActions;
00198 
00199     virtual ~DefineButtonTag();
00200 
00202     DisplayObject* createDisplayObject(Global_as& gl, DisplayObject* parent)
00203         const;
00204 
00207     ButtonRecords& buttonRecords() { return _buttonRecords; }
00208     
00210     const ButtonRecords& buttonRecords() const { return _buttonRecords; }
00211 
00213     bool hasSound() const { return (_soundTag.get()); }
00214 
00217     void addSoundTag(std::auto_ptr<SWF::DefineButtonSoundTag> soundTag) {
00218         // Do not replace a sound tag.
00219         assert(!_soundTag.get());
00220         _soundTag.reset(soundTag.release());
00221     }
00222 
00224     //
00227     const DefineButtonSoundTag::ButtonSound& buttonSound(size_t index) const {
00228         assert(_soundTag.get());
00229         return _soundTag->getSound(index);
00230     }
00231 
00233     int getSWFVersion() const;
00234 
00236     bool trackAsMenu() const {
00237         return _trackAsMenu;
00238     }
00239 
00240     bool hasKeyPressHandler() const;
00241 
00243     //
00246     template <class E>
00247     void forEachTrigger(const event_id& ev, E& f) const {
00248         for (size_t i = 0, e = _buttonActions.size(); i < e; ++i) {
00249             const ButtonAction& ba = _buttonActions[i];
00250             if (ba.triggeredBy(ev)) f(ba._actions);
00251         }
00252     }
00253 
00255     //
00258     template<class E>
00259     void visitKeyCodes(E& f) const {
00260         std::for_each(_buttonActions.begin(), _buttonActions.end(),
00261             boost::bind(f, boost::bind(
00262                     boost::mem_fn(&ButtonAction::getKeyCode), _1)));
00263     }
00264     
00265 private:
00266 
00268     friend class DefineButton2Tag;
00269 
00271     //
00273     DefineButtonTag(SWFStream& in, movie_definition& m, TagType tag, 
00274             boost::uint16_t id);
00275 
00277     void readDefineButtonTag(SWFStream& in, movie_definition& m);
00278 
00280     void readDefineButton2Tag(SWFStream& in, movie_definition& m);
00281 
00282     boost::scoped_ptr<SWF::DefineButtonSoundTag> _soundTag;
00283 
00284     ButtonRecords _buttonRecords;
00285 
00286     ButtonActions _buttonActions;
00287 
00289     bool _trackAsMenu;
00290 
00292     movie_definition& _movieDef;
00293 };
00294 
00296 //
00299 class DefineButton2Tag
00300 {
00301 public:
00303     static void loader(SWFStream& in, TagType tag, movie_definition& m, 
00304             const RunResources& r);
00305 };
00306 
00307 }
00308 }    // end namespace gnash
00309 
00310 
00311 #endif // GNASH_BUTTON_CHARACTER_DEF_H
00312 
00313 
00314 // Local Variables:
00315 // mode: C++
00316 // c-basic-offset: 8 
00317 // tab-width: 8
00318 // indent-tabs-mode: t
00319 // End: