1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #ifndef INCLUDED_SLIDESHOW_USEREVENTQUEUE_HXX
29 #define INCLUDED_SLIDESHOW_USEREVENTQUEUE_HXX
30 
31 #include <com/sun/star/animations/XAnimationNode.hpp>
32 
33 #include "eventmultiplexer.hxx"
34 #include "eventqueue.hxx"
35 #include "shape.hxx"
36 
37 #include <boost/noncopyable.hpp>
38 
39 /* Definition of UserEventQueue class */
40 
41 namespace slideshow {
42 namespace internal {
43 
44 class PlainEventHandler;
45 class AllAnimationEventHandler;
46 class ShapeClickEventHandler;
47 class ClickEventHandler;
48 class CursorManager;
49 class SkipEffectEventHandler;
50 class RewindEffectEventHandler;
51 class MouseEnterHandler;
52 class MouseLeaveHandler;
53 
54 /** This class schedules user-activated events.
55 
56     This class registeres at the EventMultiplexer and fires
57     events registered for certain user actions. Note that all
58     events will not be fired immediately after the user action
59     occured, but always added to the EventQueue (and fired the
60     next time that queue is processed). Which is actually a
61     feature.
62 
63     Conceptually, an event is an object that typically is
64     fired only once. After that, the event is exhausted, and
65     should be discarded. Therefore, all events registered on
66     this object are fired and then all references to them are
67     removed.
68 */
69 class UserEventQueue : private ::boost::noncopyable
70 {
71 public:
72     /** Create a user event queue
73 
74         @param rEventMultiplexer
75         The slideshow-global event source, where this class
76         registeres its event handlers.
77 
78         @param rEventQueue
79         Reference to the main event queue. Since we hold this
80         object by plain reference, it must live longer than we
81         do. On the other hand, that queue must not fire events
82         after this object is destroyed, since we might
83         schedule events there which itself contain plain
84         references to this object. Basically, EventQueue and
85         UserEventQueue should have the same lifetime, and since
86         this is not possible, both must be destructed in a
87         phased mode: first clear both of any remaining events,
88         then destruct them.
89     */
90     UserEventQueue( EventMultiplexer&   rMultiplexer,
91                     EventQueue&         rEventQueue,
92                     CursorManager&      rCursorManager );
93     ~UserEventQueue();
94 
95     /** Query whether there are any events still pending.
96      */
97     bool isEmpty() const;
98 
99     /** Clear all registered events.
100 
101         This method clears all registered, but
102         not-yet-executed events. This comes in handy when
103         force-ending a slide, to avoid interference with the
104         next slide's event registration.
105     */
106     void clear();
107 
108     /** Set advance on click behaviour.
109 
110         @param bAdvanceOnClick
111         When true, a click somewhere on the slide will also
112         generate next effect event.  In this case, it is
113         irrelevant where on the slide the mouse is clicked,
114         i.e. the shape need not be hit by the mouse.
115     */
116     void setAdvanceOnClick( bool bAdvanceOnClick );
117 
118     /** Register an event that will be fired when the slide is
119         just shown.
120 
121         Note that <em>all</em> registered events will be fired
122         when the slide start occurs. This is in contrast to
123         the mouse events below.
124     */
125     void registerSlideStartEvent( const EventSharedPtr& rEvent );
126 
127     /** Register an event that will be fired when the slide is
128         about to vanish.
129 
130         Note that <em>all</em> registered events will be fired
131         when the slide end occurs. This is in contrast to
132         the mouse events below.
133     */
134     void registerSlideEndEvent( const EventSharedPtr& rEvent );
135 
136     /** Register an event that will be fired when the given
137         animation node starts.
138 
139         Note that <em>all</em> registered events will be fired
140         when the animation start occurs. This is in contrast to
141         the mouse events below.
142     */
143     void registerAnimationStartEvent(
144         const EventSharedPtr&                             rEvent,
145         const ::com::sun::star::uno::Reference<
146         ::com::sun::star::animations::XAnimationNode>&    xNode );
147 
148     /** Register an event that will be fired when the given
149         animation node ends its active duration.
150 
151         Note that <em>all</em> registered events will be fired
152         when the animation end occurs. This is in contrast to
153         the mouse events below.
154     */
155     void registerAnimationEndEvent(
156         const EventSharedPtr&                               rEvent,
157         const ::com::sun::star::uno::Reference<
158         ::com::sun::star::animations::XAnimationNode>&      xNode );
159 
160     /** Register an event that will be fired when audio output
161         stopped for the given animation node.
162 
163         Note that <em>all</em> registered events will be fired
164         when the audio stopping occurs. This is in contrast to
165         the mouse events below.
166     */
167     void registerAudioStoppedEvent(
168         const EventSharedPtr&                               rEvent,
169         const ::com::sun::star::uno::Reference<
170         ::com::sun::star::animations::XAnimationNode>&      xNode );
171 
172     /** Register an event that is fired when a shape is clicked
173 
174         For every mouse click, only one of the events
175         registered here is fired. The order of fired events is
176         the order of registration, i.e. the first event
177         registered will be the one fired for the first mouse
178         click on the given shape.
179     */
180     void registerShapeClickEvent( const EventSharedPtr& rEvent,
181                                   const ShapeSharedPtr& rShape );
182 
183     /** Registes an event that is fired when the current effects(s)
184         are skipped, .e.g. when the left mouse button is pressed.
185         Then, all registered events are fired and removed from this
186         queue.  After firing, a next effect event is issued to this
187         queue to start the next effect.
188         @param pEvent
189             The event to execute when skipping the current effect.
190         @param bSkipTriggersNextEffect
191             When <TRUE/> then after skipping the current effect the next
192             effect is triggered.  When <FALSE/> then the next effect is not
193             triggered.
194     */
195     void registerSkipEffectEvent(
196         EventSharedPtr const& pEvent,
197         const bool bSkipTriggersNextEffect);
198 
199     /** Registes an event that is fired when the current effects(s)
200         are rewound, .e.g. when the right mouse button is pressed.
201         Then, all registered events are fired and removed from this
202         queue.
203     */
204     void registerRewindEffectEvent( EventSharedPtr const& rEvent );
205 
206     /** Register an event that is fired to show the next event
207 
208         For every next effect event, only one of the events
209         registered here is fired. The order of fired events is
210         the order of registration, i.e. the first event
211         registered will be the one fired for the first mouse
212         click. When advance-on-click (see method
213         setAdvanceOnClick()) is enabled, a mouse click
214         somewhere on the slide will also generate a next
215         effect event. In this case, it is irrelevant where on
216         the slide the mouse is clicked, i.e. the shape need
217         not be hit by the mouse.
218     */
219     void registerNextEffectEvent( const EventSharedPtr& rEvent );
220 
221     /** Register an event that is fired on a double mouse
222         click on a shape
223 
224         For every mouse double click, only one of the events
225         registered here is fired. The order of fired events is
226         the order of registration, i.e. the first event
227         registered will be the one fired for the first mouse
228         double click. It is irrelevant where on the slide the
229         mouse is clicked, i.e. the shape need not be hit by
230         the mouse.
231     */
232     void registerShapeDoubleClickEvent( const EventSharedPtr& rEvent,
233                                         const ShapeSharedPtr& rShape );
234 
235     /** Register an event that is fired on a double mouse click
236 
237         For every mouse double click, only one of the events
238         registered here is fired. The order of fired events is
239         the order of registration, i.e. the first event
240         registered will be the one fired for the first mouse
241         double click. It is irrelevant where on the slide the
242         mouse is clicked, i.e. the shape need not be hit by
243         the mouse.
244     */
245     void registerDoubleClickEvent( const EventSharedPtr& rEvent );
246 
247     /** Register an event that is fired when the mouse enters
248         the area of the given shape
249 
250         For every enter, only one of the events registered
251         here is fired. The order of fired events is the order
252         of registration, i.e. the first event registered will
253         be the one fired for the first time the mouse enters
254         the given shape.
255     */
256     void registerMouseEnterEvent( const EventSharedPtr& rEvent,
257                                   const ShapeSharedPtr& rShape );
258 
259     /** Register an event that is fired when the mouse leaves
260         the area of the given shape
261 
262         For every leave, only one of the events registered
263         here is fired. The order of fired events is the order
264         of registration, i.e. the first event registered will
265         be the one fired for the first time the mouse leaves
266         the given shape area.
267     */
268     void registerMouseLeaveEvent( const EventSharedPtr& rEvent,
269                                   const ShapeSharedPtr& rShape );
270 
271     /** Typically skipping the current effect is triggered by mouse clicks
272         or key presses that trigger the next effect.  This method allows the
273         skipping of effects to be triggered programatically.
274     */
275     void callSkipEffectEventHandler (void);
276 
277 private:
278     /** Generically register an event on one of the handlers.
279 
280         If the handler is not yet created, do that and
281         register it via the Functor
282     */
283     template< typename Handler, typename Functor >
284     void registerEvent( ::boost::shared_ptr< Handler >& rHandler,
285                         const EventSharedPtr&           rEvent,
286                         const Functor&                  rRegistrationFunctor );
287 
288     /** Generically register an event on one of the handlers.
289 
290         If the handler is not yet created, do that and
291         register it via the Functor. This version of the
292         registerEvent method takes an additional parameter
293         rArg, which is passed as the second argument to
294         rHandler's addEvent() method.
295     */
296     template< typename Handler, typename Arg, typename Functor >
297     void registerEvent( ::boost::shared_ptr< Handler >& rHandler,
298                         const EventSharedPtr&           rEvent,
299                         const Arg&                      rArg,
300                         const Functor&                  rRegistrationFunctor );
301 
302     EventMultiplexer&                               mrMultiplexer;
303     EventQueue&                                     mrEventQueue;
304     CursorManager&                                  mrCursorManager;
305 
306     ::boost::shared_ptr<PlainEventHandler>          mpStartEventHandler;
307     ::boost::shared_ptr<PlainEventHandler>          mpEndEventHandler;
308     ::boost::shared_ptr<AllAnimationEventHandler>   mpAnimationStartEventHandler;
309     ::boost::shared_ptr<AllAnimationEventHandler>   mpAnimationEndEventHandler;
310     ::boost::shared_ptr<AllAnimationEventHandler>   mpAudioStoppedEventHandler;
311     ::boost::shared_ptr<ShapeClickEventHandler>     mpShapeClickEventHandler;
312     ::boost::shared_ptr<ClickEventHandler>          mpClickEventHandler;
313     ::boost::shared_ptr<SkipEffectEventHandler>     mpSkipEffectEventHandler;
314     ::boost::shared_ptr<RewindEffectEventHandler>   mpRewindEffectEventHandler;
315     ::boost::shared_ptr<ShapeClickEventHandler>     mpShapeDoubleClickEventHandler;
316     ::boost::shared_ptr<ClickEventHandler>          mpDoubleClickEventHandler;
317     ::boost::shared_ptr<MouseEnterHandler>          mpMouseEnterHandler;
318     ::boost::shared_ptr<MouseLeaveHandler>          mpMouseLeaveHandler;
319 
320     bool                                            mbAdvanceOnClick;
321 };
322 
323 } // namespace internal
324 } // namespace presentation
325 
326 #endif /* INCLUDED_SLIDESHOW_USEREVENTQUEUE_HXX */
327 
328