1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #ifndef INCLUDED_SLIDESHOW_EFFECT_REWINDER_HXX
25 #define INCLUDED_SLIDESHOW_EFFECT_REWINDER_HXX
26 
27 #include "animationnode.hxx"
28 #include "eventhandler.hxx"
29 #include "animationeventhandler.hxx"
30 #include "event.hxx"
31 #include "screenupdater.hxx"
32 
33 #include <com/sun/star/presentation/XSlideShow.hpp>
34 #include <boost/scoped_ptr.hpp>
35 #include <boost/function.hpp>
36 #include <vector>
37 
38 namespace css = ::com::sun::star;
39 
40 namespace slideshow { namespace internal {
41 
42 class EventMultiplexer;
43 class EventQueue;
44 class UserEventQueue;
45 
46 /** Rewind single effects of the main effect sequence.  A rewind is
47     initiated by calling the Rewind() method.  Part of the processing is
48     done asynchronously.  Multiple EventQueue::update() calls may be
49     necessary to finish a rewind.
50 
51     Remember to call SetRootAnimationNode() when switching to a different
52     slide so that the EffectRewinder can determine the number of main
53     sequence effects.
54 */
55 class EffectRewinder
56 {
57 public:
58     EffectRewinder (
59         EventMultiplexer& rEventMultiplexer,
60         EventQueue& rEventQueue,
61         UserEventQueue& rUserEventQueue);
62     ~EffectRewinder (void);
63 
64     /** Call Dispose() before the ownder of an EffectRewinder object dies so
65         that the EffectRewinder can release all references to the owner.
66 
67     */
68     void dispose (void);
69 
70     /** Store the root node of the animation tree.  It is used in
71         CountMainSequenceEffects() to count the number of main sequence
72         effects (or effect groups.)
73     */
74     void setRootAnimationNode (
75         const css::uno::Reference<css::animations::XAnimationNode>& xRootNode);
76 
77     /** Rewind one effect of the main effect sequence.  When the current
78         slide has not effects or no main sequence effect has yet been played
79         then switch to the previous slide and replay all of its main
80         sequence effects.
81         The caller has to pass two functors that redisplay the current slide
82         or switch to the previous slide so that it does not have to expose
83         its internals to us.  Only one of the two functors is called.
84         @param rpPaintLock
85             This paint lock is released after the whole asynchronous
86             procoess  of rewinding the current effect is completed.  It
87             prevents intermediate repaints  that would show partial replay
88             of effects.
89         @param rSlideRewindFunctor
90             This functor is called when the current slide is to be
91             redisplayed.  When it is called then the other functor is not
92             called.
93         @param rPreviousSlideFunctor
94             This functor is called to switch to the previous slide.  When it
95             is called then the other functor is not called.
96     */
97     bool rewind (
98         const ::boost::shared_ptr<ScreenUpdater::UpdateLock>& rpPaintLock,
99         const ::boost::function<void(void)>& rSlideRewindFunctor,
100         const ::boost::function<void(void)>& rPreviousSlideFunctor);
101 
102     /** Call this method after gotoPreviousEffect() triggered a slide change
103         to the previous slide.
104     */
105     void skipAllMainSequenceEffects (void);
106 
107 private:
108     EventMultiplexer& mrEventMultiplexer;
109     EventQueue& mrEventQueue;
110     UserEventQueue& mrUserEventQueue;
111 
112     EventHandlerSharedPtr mpSlideStartHandler;
113     EventHandlerSharedPtr mpSlideEndHandler;
114     AnimationEventHandlerSharedPtr mpAnimationStartHandler;
115 
116     /** The number off main sequence effects so far.
117     */
118     sal_Int32 mnMainSequenceEffectCount;
119 
120     /** This is the currently scheduled event that executes the asynchronous
121         part of the effect rewinding.  It is also used as flag that prevents
122         nested rewinds.
123     */
124     EventSharedPtr mpAsynchronousRewindEvent;
125 
126     css::uno::Reference<css::animations::XAnimationNode> mxCurrentAnimationRootNode;
127     ::boost::shared_ptr<ScreenUpdater::UpdateLock> mpPaintLock;
128 
129     bool mbNonUserTriggeredMainSequenceEffectSeen;
130 
131     void initialize (void);
132 
133     bool resetEffectCount (void);
134     /** Called by listeners when an animation (not necessarily of a main
135         sequence effect) starts.
136     */
137     bool notifyAnimationStart (const AnimationNodeSharedPtr& rpNode);
138 
139     /** Count the number of effects (or effect groups) in the main effect
140         sequence.
141     */
142     sal_Int32 countMainSequenceEffects (void);
143 
144     /** Skip the next main sequence effect.
145     */
146     void skipSingleMainSequenceEffects (void);
147 
148     /** Skip the specified number of main sequence effects.
149     */
150     void skipSomeMainSequenceEffects (const sal_Int32 nSkipCount);
151 
152     /** Rewind the last effect of the main effect sequence by replaying all
153         previous effects.
154         @param nEffectCount
155             The number of main sequence effects to replay.
156         @param bRedisplayCurrentSlide
157             When <TRUE/> then the current slide is redisplayed before the
158             effects are replayed.
159         @param rSlideRewindFunctor
160             This functor is used to redisplay the current slide.
161     */
162     void asynchronousRewind (
163         sal_Int32 nEffectCount,
164         const bool bRedisplayCurrentSlide,
165         const boost::function<void(void)>& rSlideRewindFunctor);
166 
167     /** Go to the previous slide and replay all of its main sequence effects
168         (or effect groups).
169         @param rPreviousSlideFunctor
170             This functor is used to go to the previous slide.
171     */
172     void asynchronousRewindToPreviousSlide (
173         const ::boost::function<void(void)>& rPreviousSlideFunctor);
174 };
175 
176 } } // end of namespace ::slideshow::internal
177 
178 #endif
179