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 <canvas/verbosetrace.hxx>
30 #include <canvas/canvastools.hxx>
31 
32 #include <com/sun/star/drawing/XShape.hpp>
33 
34 #include "mediashape.hxx"
35 #include "viewmediashape.hxx"
36 #include "externalshapebase.hxx"
37 #include "slideshowcontext.hxx"
38 #include "shape.hxx"
39 #include "tools.hxx"
40 
41 #include <boost/bind.hpp>
42 #include <algorithm>
43 
44 
45 using namespace ::com::sun::star;
46 
47 
48 namespace slideshow
49 {
50     namespace internal
51     {
52         /** Represents a media shape.
53 
54             This implementation offers support for media shapes.
55 			Such shapes need special treatment.
56          */
57         class MediaShape : public ExternalShapeBase
58         {
59         public:
60             /** Create a shape for the given XShape for a media object
61 
62             	@param xShape
63                 The XShape to represent.
64 
65                 @param nPrio
66                 Externally-determined shape priority (used e.g. for
67                 paint ordering). This number _must be_ unique!
68              */
69             MediaShape( const ::com::sun::star::uno::Reference<
70                        		::com::sun::star::drawing::XShape >&	xShape,
71                         double										nPrio,
72                         const SlideShowContext&                     rContext ); // throw ShapeLoadFailedException;
73 
74         private:
75 
76             // View layer methods
77             //------------------------------------------------------------------
78 
79             virtual void addViewLayer( const ViewLayerSharedPtr& 	rNewLayer,
80                                        bool							bRedrawLayer );
81             virtual bool removeViewLayer( const ViewLayerSharedPtr& rNewLayer );
82             virtual bool clearAllViewLayers();
83 
84 
85             // ExternalShapeBase methods
86             //------------------------------------------------------------------
87 
88             virtual bool implRender( const ::basegfx::B2DRange& rCurrBounds ) const;
89             virtual void implViewChanged( const UnoViewSharedPtr& rView );
90             virtual void implViewsChanged();
91             virtual bool implStartIntrinsicAnimation();
92             virtual bool implEndIntrinsicAnimation();
93             virtual bool implPauseIntrinsicAnimation();
94             virtual bool implIsIntrinsicAnimationPlaying() const;
95             virtual void implSetIntrinsicAnimationTime(double);
96 
97             /// the list of active view shapes (one for each registered view layer)
98             typedef ::std::vector< ViewMediaShapeSharedPtr > ViewMediaShapeVector;
99             ViewMediaShapeVector                             maViewMediaShapes;
100             bool                                             mbIsPlaying;
101         };
102 
103 
104         MediaShape::MediaShape( const uno::Reference< drawing::XShape >& xShape,
105                               	double									 nPrio,
106                                 const SlideShowContext&                  rContext ) :
107             ExternalShapeBase( xShape, nPrio, rContext ),
108             maViewMediaShapes(),
109             mbIsPlaying(false)
110         {
111         }
112 
113 		// ---------------------------------------------------------------------
114 
115         void MediaShape::implViewChanged( const UnoViewSharedPtr& rView )
116         {
117             // determine ViewMediaShape that needs update
118             ViewMediaShapeVector::const_iterator       aIter(maViewMediaShapes.begin());
119             ViewMediaShapeVector::const_iterator const aEnd (maViewMediaShapes.end());
120             while( aIter != aEnd )
121             {
122                 if( (*aIter)->getViewLayer()->isOnView(rView) )
123                     (*aIter)->resize(getBounds());
124 
125                 ++aIter;
126             }
127         }
128 
129 		// ---------------------------------------------------------------------
130 
131         void MediaShape::implViewsChanged()
132         {
133             // resize all ViewShapes
134             ::std::for_each( maViewMediaShapes.begin(),
135                              maViewMediaShapes.end(),
136                              ::boost::bind(
137                                  &ViewMediaShape::resize,
138                                  _1,
139                                  ::boost::cref( getBounds())) );
140         }
141 
142 		// ---------------------------------------------------------------------
143 
144         void MediaShape::addViewLayer( const ViewLayerSharedPtr& rNewLayer,
145                                        bool						 bRedrawLayer )
146         {
147             maViewMediaShapes.push_back(
148                 ViewMediaShapeSharedPtr( new ViewMediaShape( rNewLayer,
149                                                              getXShape(),
150                                                              mxComponentContext )));
151 
152             // push new size to view shape
153             maViewMediaShapes.back()->resize( getBounds() );
154 
155             // render the Shape on the newly added ViewLayer
156             if( bRedrawLayer )
157                 maViewMediaShapes.back()->render( getBounds() );
158         }
159 
160 		// ---------------------------------------------------------------------
161 
162         bool MediaShape::removeViewLayer( const ViewLayerSharedPtr& rLayer )
163         {
164             const ViewMediaShapeVector::iterator aEnd( maViewMediaShapes.end() );
165 
166             OSL_ENSURE( ::std::count_if(maViewMediaShapes.begin(),
167                                         aEnd,
168                                         ::boost::bind<bool>(
169                                             ::std::equal_to< ViewLayerSharedPtr >(),
170                                             ::boost::bind( &ViewMediaShape::getViewLayer, _1 ),
171                                             ::boost::cref( rLayer ) ) ) < 2,
172                         "MediaShape::removeViewLayer(): Duplicate ViewLayer entries!" );
173 
174             ViewMediaShapeVector::iterator aIter;
175 
176             if( (aIter=::std::remove_if( maViewMediaShapes.begin(),
177                                          aEnd,
178                                          ::boost::bind<bool>(
179                                              ::std::equal_to< ViewLayerSharedPtr >(),
180                                              ::boost::bind( &ViewMediaShape::getViewLayer,
181                                                             _1 ),
182                                              ::boost::cref( rLayer ) ) )) == aEnd )
183             {
184                 // view layer seemingly was not added, failed
185                 return false;
186             }
187 
188             // actually erase from container
189             maViewMediaShapes.erase( aIter, aEnd );
190 
191             return true;
192         }
193 
194 		// ---------------------------------------------------------------------
195 
196         bool MediaShape::clearAllViewLayers()
197         {
198             maViewMediaShapes.clear();
199             return true;
200         }
201 
202 		// ---------------------------------------------------------------------
203 
204         bool MediaShape::implRender( const ::basegfx::B2DRange& rCurrBounds ) const
205         {
206             // redraw all view shapes, by calling their update() method
207             if( ::std::count_if( maViewMediaShapes.begin(),
208                                  maViewMediaShapes.end(),
209                                  ::boost::bind<bool>(
210                                      ::boost::mem_fn( &ViewMediaShape::render ),
211                                      _1,
212                                      ::boost::cref( rCurrBounds ) ) )
213                 != static_cast<ViewMediaShapeVector::difference_type>(maViewMediaShapes.size()) )
214             {
215                 // at least one of the ViewShape::update() calls did return
216                 // false - update failed on at least one ViewLayer
217                 return false;
218             }
219 
220             return true;
221         }
222 
223 		// ---------------------------------------------------------------------
224 
225         bool MediaShape::implStartIntrinsicAnimation()
226         {
227             ::std::for_each( maViewMediaShapes.begin(),
228                              maViewMediaShapes.end(),
229                              ::boost::mem_fn( &ViewMediaShape::startMedia ) );
230 
231             mbIsPlaying = true;
232 
233             return true;
234         }
235 
236 		// ---------------------------------------------------------------------
237 
238         bool MediaShape::implEndIntrinsicAnimation()
239         {
240             ::std::for_each( maViewMediaShapes.begin(),
241                              maViewMediaShapes.end(),
242                              ::boost::mem_fn( &ViewMediaShape::endMedia ) );
243 
244             mbIsPlaying = false;
245 
246             return true;
247         }
248 
249 		// ---------------------------------------------------------------------
250 
251         bool MediaShape::implPauseIntrinsicAnimation()
252         {
253             ::std::for_each( maViewMediaShapes.begin(),
254                              maViewMediaShapes.end(),
255                              ::boost::mem_fn( &ViewMediaShape::pauseMedia ) );
256 
257             mbIsPlaying = false;
258 
259             return true;
260         }
261 
262 		// ---------------------------------------------------------------------
263 
264         bool MediaShape::implIsIntrinsicAnimationPlaying() const
265         {
266             return mbIsPlaying;
267         }
268 
269 		// ---------------------------------------------------------------------
270 
271         void MediaShape::implSetIntrinsicAnimationTime(double fTime)
272         {
273             ::std::for_each( maViewMediaShapes.begin(),
274                              maViewMediaShapes.end(),
275                              ::boost::bind( &ViewMediaShape::setMediaTime,
276                                             _1, boost::cref(fTime)) );
277         }
278 
279 		// ---------------------------------------------------------------------
280 
281         ShapeSharedPtr createMediaShape(
282             const uno::Reference< drawing::XShape >& xShape,
283             double                                   nPrio,
284             const SlideShowContext&                  rContext)
285         {
286             boost::shared_ptr< MediaShape > pMediaShape(
287                 new MediaShape(xShape, nPrio, rContext));
288 
289             return pMediaShape;
290         }
291 
292     }
293 }
294