]> git.mxchange.org Git - flightgear.git/blob - src/Canvas/elements/group.cxx
Canvas: Forward mouse events to elements.
[flightgear.git] / src / Canvas / elements / group.cxx
1 // A group of 2D canvas elements
2 //
3 // Copyright (C) 2012  Thomas Geymayer <tomgey@gmail.com>
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 as
7 // published by the Free Software Foundation; either version 2 of the
8 // License, or (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful, but
11 // WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 // 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 Street, Fifth Floor, Boston, MA  02110-1301, USA.
18
19 #include "group.hxx"
20 #include "map.hxx"
21 #include "path.hxx"
22 #include "text.hxx"
23 #include "CanvasImage.hxx"
24
25 #include <boost/foreach.hpp>
26
27 namespace canvas
28 {
29
30   //----------------------------------------------------------------------------
31   Group::Group(SGPropertyNode_ptr node):
32     Element(node)
33   {
34
35   }
36
37   //----------------------------------------------------------------------------
38   Group::~Group()
39   {
40
41   }
42
43   //----------------------------------------------------------------------------
44   void Group::update(double dt)
45   {
46     BOOST_FOREACH( ChildList::value_type child, _children )
47       child.second->update(dt);
48
49     Element::update(dt);
50   }
51
52   //----------------------------------------------------------------------------
53   bool Group::handleLocalMouseEvent(const canvas::MouseEvent& event)
54   {
55     // Iterate in reverse order as last child is displayed on top
56     BOOST_REVERSE_FOREACH( ChildList::value_type child, _children )
57     {
58       if( child.second->handleMouseEvent(event) )
59         return true;
60     }
61     return false;
62   }
63
64   //----------------------------------------------------------------------------
65   void Group::childAdded(SGPropertyNode* child)
66   {
67     boost::shared_ptr<Element> element;
68
69     // TODO create map of child factories and use also to check for element
70     //      on deletion in ::childRemoved
71     if( child->getNameString() == "text" )
72       element.reset( new Text(child) );
73     else if( child->getNameString() == "group" )
74       element.reset( new Group(child) );
75     else if( child->getNameString() == "map" )
76       element.reset( new Map(child) );
77     else if( child->getNameString() == "path" )
78       element.reset( new Path(child) );
79     else if( child->getNameString() == "image" )
80       element.reset( new Image(child) );
81
82     if( !element )
83       return;
84
85     // Add to osg scene graph...
86     _transform->addChild( element->getMatrixTransform() );
87     _children.push_back( ChildList::value_type(child, element) );
88   }
89
90   //----------------------------------------------------------------------------
91   struct ChildFinder
92   {
93     public:
94       ChildFinder(SGPropertyNode *node):
95         _node(node)
96       {}
97
98       bool operator()(const Group::ChildList::value_type& el) const
99       {
100         return el.first == _node;
101       }
102
103     private:
104       SGPropertyNode *_node;
105   };
106
107   //----------------------------------------------------------------------------
108   void Group::childRemoved(SGPropertyNode* node)
109   {
110     if(    node->getNameString() == "text"
111         || node->getNameString() == "group"
112         || node->getNameString() == "map"
113         || node->getNameString() == "path"
114         || node->getNameString() == "image" )
115     {
116       ChildFinder pred(node);
117       ChildList::iterator child =
118         std::find_if(_children.begin(), _children.end(), pred);
119
120       if( child == _children.end() )
121         SG_LOG
122         (
123           SG_GL,
124           SG_WARN,
125           "can't removed unknown child " << node->getDisplayName()
126         );
127       else
128       {
129         _transform->removeChild( child->second->getMatrixTransform() );
130         _children.erase(child);
131       }
132     }
133   }
134
135 } // namespace canvas