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 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_slideshow.hxx"
26 
27 // must be first
28 #include <canvas/debug.hxx>
29 #include <tools/diagnose_ex.h>
30 #include <canvas/verbosetrace.hxx>
31 
32 #include <com/sun/star/drawing/XShape.hpp>
33 #include <com/sun/star/animations/XAnimationNode.hpp>
34 #include <com/sun/star/animations/Timing.hpp>
35 #include <com/sun/star/animations/EventTrigger.hpp>
36 #include <com/sun/star/animations/Event.hpp>
37 
38 #include "shape.hxx"
39 #include "subsettableshapemanager.hxx"
40 #include "usereventqueue.hxx"
41 #include "slideshowcontext.hxx"
42 #include "delayevent.hxx"
43 
44 namespace slideshow {
45 namespace internal {
46 
47 using namespace com::sun::star;
48 
generateEvent(uno::Any const & rEventDescription,Delay::FunctorT const & rFunctor,SlideShowContext const & rContext,double nAdditionalDelay)49 EventSharedPtr generateEvent(
50     uno::Any const& rEventDescription,
51     Delay::FunctorT const& rFunctor,
52     SlideShowContext const& rContext,
53     double nAdditionalDelay )
54 {
55     EventSharedPtr pEvent;
56 
57     if (! rEventDescription.hasValue())
58         return pEvent;
59 
60     animations::Timing eTiming;
61     animations::Event aEvent;
62     uno::Sequence<uno::Any> aSequence;
63     double nDelay1 = 0;
64 
65     if (rEventDescription >>= eTiming) {
66         switch (eTiming) {
67         case animations::Timing_INDEFINITE:
68             break; // don't schedule no event
69         case animations::Timing_MEDIA:
70             OSL_ENSURE( false, "MEDIA timing not yet implemented!" );
71             break;
72         default:
73             ENSURE_OR_THROW( false, "unexpected case!" );
74         }
75     }
76     else if (rEventDescription >>= aEvent) {
77 
78         // try to extract additional event delay
79         double nDelay2 = 0.0;
80         if (aEvent.Offset.hasValue() && !(aEvent.Offset >>= nDelay2)) {
81             OSL_ENSURE( false, "offset values apart from DOUBLE not "
82                         "recognized in animations::Event!" );
83         }
84 
85         // common vars used inside switch
86         uno::Reference<animations::XAnimationNode> xNode;
87         uno::Reference<drawing::XShape> xShape;
88         ShapeSharedPtr pShape;
89 
90         // TODO(F1): Respect aEvent.Repeat value
91 
92         switch (aEvent.Trigger) {
93         default:
94             ENSURE_OR_THROW( false, "unexpected event trigger!" );
95         case animations::EventTrigger::NONE:
96             // no event at all
97             break;
98         case animations::EventTrigger::ON_BEGIN:
99             OSL_ENSURE( false, "event trigger ON_BEGIN not yet implemented!" );
100             break;
101         case animations::EventTrigger::ON_END:
102             OSL_ENSURE( false, "event trigger ON_END not yet implemented!" );
103             break;
104         case animations::EventTrigger::BEGIN_EVENT:
105             // try to extract XAnimationNode event source
106             if (aEvent.Source >>= xNode) {
107                 pEvent = makeDelay( rFunctor,
108                                     nDelay2 + nAdditionalDelay,
109                                     "generateEvent, BEGIN_EVENT");
110                 rContext.mrUserEventQueue.registerAnimationStartEvent(
111                     pEvent, xNode );
112             }
113             else {
114                 OSL_ENSURE(false, "could not extract source XAnimationNode "
115                            "for BEGIN_EVENT!" );
116             }
117             break;
118         case animations::EventTrigger::END_EVENT:
119             // try to extract XAnimationNode event source
120             if (aEvent.Source >>= xNode) {
121                 pEvent = makeDelay( rFunctor,
122                                     nDelay2 + nAdditionalDelay,
123                                     "generateEvent, END_EVENT");
124                 rContext.mrUserEventQueue.registerAnimationEndEvent(
125                     pEvent, xNode );
126             }
127             else {
128                 OSL_ENSURE( false, "could not extract source XAnimationNode "
129                             "for END_EVENT!" );
130             }
131             break;
132         case animations::EventTrigger::ON_CLICK:
133             // try to extract XShape event source
134             if ((aEvent.Source >>= xShape) &&
135                 (pShape = rContext.mpSubsettableShapeManager->lookupShape(xShape)).get())
136             {
137                 pEvent = makeDelay( rFunctor,
138                                     nDelay2 + nAdditionalDelay,
139                                     "generateEvent, ON_CLICK");
140                 rContext.mrUserEventQueue.registerShapeClickEvent(
141                     pEvent, pShape );
142             }
143             else {
144                 OSL_ENSURE( false, "could not extract source XAnimationNode "
145                             "for ON_CLICK!" );
146             }
147             break;
148         case animations::EventTrigger::ON_DBL_CLICK:
149             // try to extract XShape event source
150             if ((aEvent.Source >>= xShape) &&
151                 (pShape = rContext.mpSubsettableShapeManager->lookupShape(xShape)).get())
152             {
153                 pEvent = makeDelay( rFunctor,
154                                     nDelay2 + nAdditionalDelay,
155                                     "generateEvent, ON_DBL_CLICK");
156                 rContext.mrUserEventQueue.registerShapeDoubleClickEvent(
157                     pEvent, pShape );
158             }
159             else {
160                 OSL_ENSURE( false, "could not extract source XAnimationNode "
161                             "for ON_DBL_CLICK!" );
162             }
163             break;
164         case animations::EventTrigger::ON_MOUSE_ENTER:
165             // try to extract XShape event source
166             if ((aEvent.Source >>= xShape) &&
167                 (pShape = rContext.mpSubsettableShapeManager->lookupShape(xShape)).get())
168             {
169                 pEvent = makeDelay( rFunctor,
170                                     nDelay2 + nAdditionalDelay,
171                                     "generateEvent, ON_MOUSE_ENTER");
172                 rContext.mrUserEventQueue.registerMouseEnterEvent(
173                     pEvent, pShape );
174             }
175             else {
176                 OSL_ENSURE( false, "could not extract source XAnimationNode "
177                             "for ON_MOUSE_ENTER!" );
178             }
179             break;
180         case animations::EventTrigger::ON_MOUSE_LEAVE:
181             // try to extract XShape event source
182             if ((aEvent.Source >>= xShape) &&
183                 (pShape = rContext.mpSubsettableShapeManager->lookupShape(xShape)).get())
184             {
185                 pEvent = makeDelay( rFunctor,
186                                     nDelay2 + nAdditionalDelay,
187                                     "generateEvent, ON_MOUSE_LEAVE");
188                 rContext.mrUserEventQueue.registerMouseLeaveEvent(
189                     pEvent, pShape );
190             }
191             else {
192                 OSL_ENSURE( false, "could not extract source XAnimationNode "
193                             "for ON_MOUSE_LEAVE!" );
194             }
195             break;
196         case animations::EventTrigger::ON_PREV:
197             OSL_ENSURE( false, "event trigger ON_PREV not yet implemented, "
198                         "mapped to ON_NEXT!" );
199             // FALLTHROUGH intended
200         case animations::EventTrigger::ON_NEXT:
201             pEvent = makeDelay( rFunctor,
202                                 nDelay2 + nAdditionalDelay,
203                                 "generateEvent, ON_NEXT");
204             rContext.mrUserEventQueue.registerNextEffectEvent( pEvent );
205             break;
206         case animations::EventTrigger::ON_STOP_AUDIO:
207             // try to extract XAnimationNode event source
208             if (aEvent.Source >>= xNode) {
209                 pEvent = makeDelay( rFunctor,
210                                     nDelay2 + nAdditionalDelay,
211                                     "generateEvent, ON_STOP_AUDIO");
212                 rContext.mrUserEventQueue.registerAudioStoppedEvent(
213                     pEvent, xNode );
214             }
215             else {
216                 OSL_ENSURE( false, "could not extract source XAnimationNode "
217                             "for ON_STOP_AUDIO!" );
218             }
219             break;
220         case animations::EventTrigger::REPEAT:
221             OSL_ENSURE( false, "event trigger REPEAT not yet implemented!" );
222             break;
223         }
224     }
225     else if (rEventDescription >>= aSequence) {
226         OSL_ENSURE( false, "sequence of timing primitives "
227                     "not yet implemented!" );
228     }
229     else if (rEventDescription >>= nDelay1) {
230         pEvent = makeDelay( rFunctor,
231                             nDelay1 + nAdditionalDelay,
232                             "generateEvent with delay");
233         // schedule delay event
234         rContext.mrEventQueue.addEvent( pEvent );
235     }
236 
237     return pEvent;
238 }
239 
240 } // namespace internal
241 } // namespace slideshow
242 
243