1 ///@file
2 /// Manage event handling inside a Canvas similar to the DOM Level 3 Event Model
3 //
4 // Copyright (C) 2012  Thomas Geymayer <tomgey@gmail.com>
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Library General Public
8 // License as published by the Free Software Foundation; either
9 // version 2 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Library General Public License for more details.
15 //
16 // You should have received a copy of the GNU Library General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA
19 
20 #ifndef CANVAS_EVENT_MANAGER_HXX_
21 #define CANVAS_EVENT_MANAGER_HXX_
22 
23 #include "canvas_fwd.hxx"
24 #include <deque>
25 
26 namespace simgear
27 {
28 namespace canvas
29 {
30 
31   struct EventTarget
32   {
33     ElementWeakPtr      element;
34 
35     // Used as storage by EventManager during event propagation
36     mutable osg::Vec2f  local_pos;
37 
EventTargetsimgear::canvas::EventTarget38     EventTarget( Element* el,
39                  const osg::Vec2f pos = osg::Vec2f() ):
40       element(el),
41       local_pos(pos)
42     {}
43   };
44 
operator ==(const EventTarget & t1,const EventTarget & t2)45   inline bool operator==(const EventTarget& t1, const EventTarget& t2)
46   {
47     return t1.element.lock() == t2.element.lock();
48   }
49 
50   class EventManager
51   {
52     public:
53       EventManager();
54 
55       bool handleEvent( const MouseEventPtr& event,
56                         const EventPropagationPath& path );
57 
58       bool propagateEvent( const EventPtr& event,
59                            const EventPropagationPath& path );
60 
61     protected:
62       struct StampedPropagationPath
63       {
64         StampedPropagationPath();
65         StampedPropagationPath(const EventPropagationPath& path, double time);
66 
67         void clear();
68         bool valid() const;
69 
70         EventPropagationPath path;
71         double time;
72       };
73 
74       // TODO if we really need the paths modify to not copy around the paths
75       //      that much.
76       StampedPropagationPath _last_mouse_over;
77       size_t _current_click_count;
78 
79       struct MouseEventInfo:
80         public StampedPropagationPath
81       {
82         int button;
83         osg::Vec2f pos;
84 
85         void set( const MouseEventPtr& event,
86                   const EventPropagationPath& path );
87       } _last_mouse_down,
88         _last_click;
89 
90       /**
91        * Propagate click event and handle multi-click (eg. create dblclick)
92        */
93       bool handleClick( const MouseEventPtr& event,
94                         const EventPropagationPath& path );
95 
96       /**
97        * Handle mouseover/enter/out/leave
98        */
99       bool handleMove( const MouseEventPtr& event,
100                        const EventPropagationPath& path );
101 
102       /**
103        * Check if two click events (either mousedown/up or two consecutive
104        * clicks) are inside a maximum distance to still create a click or
105        * dblclick event respectively.
106        */
107       bool checkClickDistance( const osg::Vec2f& pos1,
108                                const osg::Vec2f& pos2 ) const;
109       EventPropagationPath
110       getCommonAncestor( const EventPropagationPath& path1,
111                          const EventPropagationPath& path2 ) const;
112   };
113 
114 } // namespace canvas
115 } // namespace simgear
116 
117 #endif /* CANVAS_EVENT_MANAGER_HXX_ */
118