]> git.mxchange.org Git - simgear.git/blob - simgear/canvas/elements/CanvasElement.hxx
Refactor Canvas and add some helpers.
[simgear.git] / simgear / canvas / elements / CanvasElement.hxx
1 // Interface for 2D Canvas elements
2 //
3 // Copyright (C) 2012  Thomas Geymayer <tomgey@gmail.com>
4 //
5 // This library is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU Library General Public
7 // License as published by the Free Software Foundation; either
8 // version 2 of the License, or (at your option) any later version.
9 //
10 // This library 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 GNU
13 // Library General Public License for more details.
14 //
15 // You should have received a copy of the GNU Library General Public
16 // License along with this library; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA
18
19 #ifndef CANVAS_ELEMENT_HXX_
20 #define CANVAS_ELEMENT_HXX_
21
22 #include <simgear/canvas/canvas_fwd.hxx>
23 #include <simgear/props/props.hxx>
24 #include <simgear/misc/stdint.hxx> // for uint32_t
25 #include <osg/BoundingBox>
26 #include <osg/MatrixTransform>
27
28 #include <boost/bind.hpp>
29 #include <boost/function.hpp>
30
31 namespace osg
32 {
33   class Drawable;
34 }
35
36 namespace simgear
37 {
38 namespace canvas
39 {
40
41   class MouseEvent;
42   class Element:
43     public SGPropertyChangeListener
44   {
45     public:
46       typedef std::map<std::string, const SGPropertyNode*> Style;
47       typedef boost::function<void(const SGPropertyNode*)> StyleSetter;
48       typedef std::map<std::string, StyleSetter> StyleSetters;
49
50       /**
51        * Remove the property listener of the element.
52        *
53        * You will need to call the appropriate methods (#childAdded,
54        * #childRemoved, #valueChanged) yourself to ensure the element still
55        * receives the needed events.
56        */
57       void removeListener();
58
59       /**
60        *
61        */
62       virtual ~Element() = 0;
63
64       /**
65        * Called every frame to update internal state
66        *
67        * @param dt  Frame time in seconds
68        */
69       virtual void update(double dt);
70
71       /**
72        * Handle mouse event (transforms coordinates to local coordinate frame
73        * and forwards event to #handleLocalMouseEvent)
74        */
75       virtual bool handleMouseEvent(const canvas::MouseEvent& event);
76
77       osg::ref_ptr<osg::MatrixTransform> getMatrixTransform();
78
79       virtual void childAdded( SGPropertyNode * parent,
80                                SGPropertyNode * child );
81       virtual void childRemoved( SGPropertyNode * parent,
82                                  SGPropertyNode * child );
83       virtual void valueChanged(SGPropertyNode * child);
84
85       /**
86        * Write the given bounding box to the property tree
87        */
88       void setBoundingBox(const osg::BoundingBox& bb);
89
90     protected:
91
92       enum Attributes
93       {
94         LAST_ATTRIBUTE  = 0x0001
95       };
96
97       enum TransformType
98       {
99         TT_NONE,
100         TT_MATRIX,
101         TT_TRANSLATE,
102         TT_ROTATE,
103         TT_SCALE
104       };
105
106       CanvasWeakPtr _canvas;
107       uint32_t _attributes_dirty;
108
109       bool _transform_dirty;
110       osg::ref_ptr<osg::MatrixTransform>    _transform;
111       std::vector<TransformType>            _transform_types;
112
113       SGPropertyNode_ptr                _node;
114       Style                             _style;
115       StyleSetters                      _style_setters;
116       std::vector<SGPropertyNode_ptr>   _bounding_box;
117
118       Element( const CanvasWeakPtr& canvas,
119                SGPropertyNode_ptr node,
120                const Style& parent_style );
121
122       template<typename T, class C1, class C2>
123       Element::StyleSetter
124       addStyle(const std::string& name, void (C1::*setter)(T), C2 instance)
125       {
126         return _style_setters[ name ] =
127                  bindStyleSetter<T>(name, setter, instance);
128       }
129
130       template<typename T1, typename T2, class C1, class C2>
131       Element::StyleSetter
132       addStyle(const std::string& name, void (C1::*setter)(T2), C2 instance)
133       {
134         return _style_setters[ name ] =
135                  bindStyleSetter<T1>(name, setter, instance);
136       }
137
138       template<class C1, class C2>
139       Element::StyleSetter
140       addStyle( const std::string& name,
141                 void (C1::*setter)(const std::string&),
142                 C2 instance )
143       {
144         return _style_setters[ name ] =
145                  bindStyleSetter<const char*>(name, setter, instance);
146       }
147
148       template<typename T1, typename T2, class C1, class C2>
149       Element::StyleSetter
150       bindStyleSetter( const std::string& name,
151                        void (C1::*setter)(T2),
152                        C2 instance )
153       {
154         return boost::bind(setter, instance, boost::bind(&getValue<T1>, _1));
155       }
156
157       virtual bool handleLocalMouseEvent(const canvas::MouseEvent& event);
158
159       virtual void childAdded(SGPropertyNode * child)  {}
160       virtual void childRemoved(SGPropertyNode * child){}
161       virtual void childChanged(SGPropertyNode * child){}
162
163       void setDrawable(osg::Drawable* drawable);
164
165       void setupStyle();
166       bool setStyle(const SGPropertyNode* child);
167
168     private:
169
170       osg::ref_ptr<osg::Drawable> _drawable;
171
172       Element(const Element&);// = delete
173   };
174
175 } // namespace canvas
176 } // namespace simgear
177
178 #endif /* CANVAS_ELEMENT_HXX_ */