1 //
2 //   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
3 //   Free Software Foundation, Inc
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 3 of the License, or
8 // (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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18 //
19 
20 // SWF buttons.  Mouse-sensitive update/display, actions, etc.
21 
22 
23 #ifndef GNASH_BUTTON_H
24 #define GNASH_BUTTON_H
25 
26 #include <boost/intrusive_ptr.hpp>
27 #include <vector>
28 #include <set>
29 
30 #include "InteractiveObject.h"
31 #include "GnashKey.h"
32 #include "dsodefs.h"
33 
34 // Forward declarations.
35 namespace gnash {
36     namespace SWF {
37         class DefineButtonTag;
38     }
39 }
40 
41 namespace gnash {
42 
43 /// Button implements Flash buttons.
44 class DSOTEXPORT Button : public InteractiveObject
45 {
46 public:
47 
48     typedef std::vector<DisplayObject*> DisplayObjects;
49     typedef std::vector<const DisplayObject*> ConstDisplayObjects;
50 
51     /// A container for holding the id of active button records.
52     typedef std::set<int> ActiveRecords;
53 
54     enum mouse_flags
55     {
56         FLAG_IDLE = 0,
57         FLAG_OVER = 1,
58         FLAG_DOWN = 2,
59         OVER_DOWN = FLAG_OVER | FLAG_DOWN,
60 
61         // aliases
62         OVER_UP = FLAG_OVER,
63         OUT_DOWN = FLAG_DOWN
64     };
65 
66     enum MouseState
67     {
68         MOUSESTATE_UP = 0,
69         MOUSESTATE_DOWN,
70         MOUSESTATE_OVER,
71         MOUSESTATE_HIT
72     };
73 
74     /// Construct a Button
75     //
76     /// A button should always have an associated object.
77     Button(as_object* object, const SWF::DefineButtonTag* def,
78             DisplayObject* parent);
79 
80     ~Button();
81 
mouseEnabled()82     bool mouseEnabled() const { return true; }
83 
84     virtual bool trackAsMenu();
85 
86     /// Handle a key press associated with a button event.
87     void keyPress(key::code c);
88 
89     /// Render this Button.
90     virtual void display(Renderer& renderer, const Transform& xform);
91 
92     void set_current_state(MouseState new_state);
93 
94     /// Return the topmost entity that the given point covers. NULL if none.
95     //
96     /// I.e. check against ourself.
97     virtual InteractiveObject* topmostMouseEntity(std::int32_t x,
98             std::int32_t y);
99 
100     /// Called whenever a mouse event affects this Button.
101     virtual void mouseEvent(const event_id& event);
102 
103     /// Called when the Button is in focus.
104     virtual bool handleFocus();
105 
106     void add_invalidated_bounds(InvalidatedRanges& ranges, bool force);
107 
108     virtual SWFRect getBounds() const;
109 
110     // See dox in DisplayObject.h
111     bool pointInShape(std::int32_t x, std::int32_t y) const;
112 
113     bool isEnabled();
114 
115     /// Properly destroy contained DisplayObjects
116     void destroy();
117 
118     /// Do ActionScript construction of the Button.
119     //
120     /// Construct all button state DisplayObjects.
121     //
122     /// @param init     An init object, which can be passed when constructing
123     ///                 Buttons with attachMovie, but is never used.
124     virtual void construct(as_object* init = nullptr);
125 
126 #ifdef USE_SWFTREE
127     // Override to append button DisplayObjects info, see dox in DisplayObject.h
128     virtual InfoTree::iterator getMovieInfo(InfoTree& tr,
129             InfoTree::iterator it);
130 #endif
131 
132 protected:
133 
134     /// Properly unload contained DisplayObjects
135     virtual bool unloadChildren();
136 
137     /// Mark reachable resources (for the GC)
138     //
139     /// These are:
140     ///    - this char's definition (_def)
141     ///    - the vector of state DisplayObjects (_stateCharacters)
142     ///    - the vector of hit DisplayObjects (_hitCharacters)
143     ///
144     void markOwnResources() const;
145 
146 private:
147 
148     /// Returns all DisplayObjects that are active based on the current state.
149     //
150     /// The "_visible" property does not matter here.
151     ///
152     /// @param list             The container to push active DisplayObjects into
153     /// @param includeUnloaded  If true, include unloaded but still reachable
154     ///                         chars in the records slot.
155     void getActiveCharacters(DisplayObjects& list, bool includeUnloaded=false);
156 
157     /// Returns all DisplayObjects that are active based on the current state.
158     //
159     /// This is a const method because the returned DisplayObjects cannot be
160     /// modified.
161     ///
162     /// @param list     The container to push unmodifiable DisplayObjects into.
163     void getActiveCharacters(ConstDisplayObjects& list) const;
164 
165     /// Returns all DisplayObjects (record nums) that should be active on
166     /// the given state.
167     //
168     /// @param list
169     ///    The set to push active DisplayObjects record number into
170     ///
171     /// @param state
172     ///    The state we're interested in
173     ///
174     void get_active_records(ActiveRecords& list, MouseState state);
175 
176     /// Return version of the SWF containing the button definition.
177     virtual int getDefinitionVersion() const;
178 
179     MouseState _mouseState;
180 
181     const boost::intrusive_ptr<const SWF::DefineButtonTag> _def;
182 
183     DisplayObjects _stateCharacters;
184 
185     DisplayObjects _hitCharacters;
186 
187 };
188 
189 std::ostream& operator<<(std::ostream& o, const Button::MouseState& st);
190 
191 /// Initialize the global Button class
192 void button_class_init(as_object& global, const ObjectURI& uri);
193 
194 void registerButtonNative(as_object& global);
195 
196 } // namespace gnash
197 
198 
199 #endif // GNASH_BUTTON_H
200 
201 
202 // Local Variables:
203 // mode: C++
204 // c-basic-offset: 8
205 // tab-width: 8
206 // indent-tabs-mode: t
207 // End:
208