170f497fbSAndrew Rist /**************************************************************
2*b06e87e7Smseidel  *
370f497fbSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
470f497fbSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
570f497fbSAndrew Rist  * distributed with this work for additional information
670f497fbSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
770f497fbSAndrew Rist  * to you under the Apache License, Version 2.0 (the
870f497fbSAndrew Rist  * "License"); you may not use this file except in compliance
970f497fbSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*b06e87e7Smseidel  *
1170f497fbSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*b06e87e7Smseidel  *
1370f497fbSAndrew Rist  * Unless required by applicable law or agreed to in writing,
1470f497fbSAndrew Rist  * software distributed under the License is distributed on an
1570f497fbSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1670f497fbSAndrew Rist  * KIND, either express or implied.  See the License for the
1770f497fbSAndrew Rist  * specific language governing permissions and limitations
1870f497fbSAndrew Rist  * under the License.
19*b06e87e7Smseidel  *
2070f497fbSAndrew Rist  *************************************************************/
2170f497fbSAndrew Rist 
2270f497fbSAndrew Rist 
23*b06e87e7Smseidel 
24cdf0e10cSrcweir #include "precompiled_slideshow.hxx"
25cdf0e10cSrcweir 
26cdf0e10cSrcweir #include <canvas/debug.hxx>
27cdf0e10cSrcweir #include <tools/diagnose_ex.h>
28cdf0e10cSrcweir #include <canvas/canvastools.hxx>
29cdf0e10cSrcweir 
30cdf0e10cSrcweir #include "eventqueue.hxx"
31cdf0e10cSrcweir #include "eventmultiplexer.hxx"
32cdf0e10cSrcweir #include "slideview.hxx"
33cdf0e10cSrcweir #include "delayevent.hxx"
34cdf0e10cSrcweir #include "unoview.hxx"
35cdf0e10cSrcweir 
36cdf0e10cSrcweir #include <rtl/instance.hxx>
37cdf0e10cSrcweir #include <cppuhelper/basemutex.hxx>
38cdf0e10cSrcweir #include <cppuhelper/compbase2.hxx>
39cdf0e10cSrcweir #include <cppuhelper/implementationentry.hxx>
40cdf0e10cSrcweir #include <cppuhelper/interfacecontainer.h>
41cdf0e10cSrcweir #include <comphelper/make_shared_from_uno.hxx>
42cdf0e10cSrcweir 
43cdf0e10cSrcweir #include <cppcanvas/spritecanvas.hxx>
44cdf0e10cSrcweir #include <cppcanvas/customsprite.hxx>
45cdf0e10cSrcweir #include <cppcanvas/vclfactory.hxx>
46cdf0e10cSrcweir #include <cppcanvas/basegfxfactory.hxx>
47cdf0e10cSrcweir 
48cdf0e10cSrcweir #include <tools/debug.hxx>
49cdf0e10cSrcweir 
50cdf0e10cSrcweir #include <basegfx/range/b1drange.hxx>
51cdf0e10cSrcweir #include <basegfx/range/b2drange.hxx>
52cdf0e10cSrcweir #include <basegfx/range/b2irange.hxx>
53cdf0e10cSrcweir #include <basegfx/point/b2dpoint.hxx>
54cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygon.hxx>
55cdf0e10cSrcweir #include <basegfx/matrix/b2dhommatrix.hxx>
56cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygontools.hxx>
57cdf0e10cSrcweir #include <basegfx/polygon/b2dpolypolygontools.hxx>
58cdf0e10cSrcweir #include <basegfx/tools/canvastools.hxx>
59cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygonclipper.hxx>
60cdf0e10cSrcweir #include <basegfx/polygon/b2dpolypolygoncutter.hxx>
61cdf0e10cSrcweir 
62cdf0e10cSrcweir #include <com/sun/star/presentation/XSlideShow.hpp>
63cdf0e10cSrcweir 
64cdf0e10cSrcweir #include <boost/noncopyable.hpp>
65cdf0e10cSrcweir #include <boost/bind.hpp>
66cdf0e10cSrcweir #include <boost/weak_ptr.hpp>
67cdf0e10cSrcweir 
68cdf0e10cSrcweir #include <vector>
69cdf0e10cSrcweir #include <iterator>
70cdf0e10cSrcweir #include <algorithm>
71cdf0e10cSrcweir 
72cdf0e10cSrcweir using namespace com::sun::star;
73cdf0e10cSrcweir 
74cdf0e10cSrcweir namespace slideshow {
75cdf0e10cSrcweir namespace internal {
76cdf0e10cSrcweir 
77cdf0e10cSrcweir namespace {
78cdf0e10cSrcweir 
79cdf0e10cSrcweir struct StaticUnitRectPoly : public rtl::StaticWithInit<basegfx::B2DPolygon, StaticUnitRectPoly>
80cdf0e10cSrcweir {
operator ()slideshow::internal::__anon55b56fc90111::StaticUnitRectPoly81cdf0e10cSrcweir     basegfx::B2DPolygon operator()()
82cdf0e10cSrcweir     {
83cdf0e10cSrcweir         return basegfx::tools::createUnitPolygon();
84cdf0e10cSrcweir     }
85cdf0e10cSrcweir };
86cdf0e10cSrcweir 
87cdf0e10cSrcweir /** Sprite entry, to store sprite plus priority
88cdf0e10cSrcweir 
89cdf0e10cSrcweir     The operator<() defines a strict weak ordering of sprites, sort
90cdf0e10cSrcweir     key is the sprite priority.
91cdf0e10cSrcweir  */
92cdf0e10cSrcweir struct SpriteEntry
93cdf0e10cSrcweir {
SpriteEntryslideshow::internal::__anon55b56fc90111::SpriteEntry94cdf0e10cSrcweir     SpriteEntry( const cppcanvas::CustomSpriteSharedPtr& rSprite,
95cdf0e10cSrcweir                  double                                  nPrio ) :
96cdf0e10cSrcweir         mpSprite( rSprite ),
97cdf0e10cSrcweir         mnPriority( nPrio )
98cdf0e10cSrcweir     {
99cdf0e10cSrcweir     }
100cdf0e10cSrcweir 
operator <slideshow::internal::__anon55b56fc90111::SpriteEntry101cdf0e10cSrcweir     bool operator<(const SpriteEntry& rRHS) const
102cdf0e10cSrcweir     {
103cdf0e10cSrcweir         return mnPriority < rRHS.mnPriority;
104cdf0e10cSrcweir     }
105cdf0e10cSrcweir 
106cdf0e10cSrcweir     boost::weak_ptr< cppcanvas::CustomSprite > mpSprite;
107cdf0e10cSrcweir     double                                     mnPriority;
108cdf0e10cSrcweir };
109cdf0e10cSrcweir 
110cdf0e10cSrcweir typedef std::vector< SpriteEntry > SpriteVector;
111cdf0e10cSrcweir 
112cdf0e10cSrcweir 
113cdf0e10cSrcweir /** Create a clip polygon for slide views
114cdf0e10cSrcweir 
115cdf0e10cSrcweir     @param rClip
116cdf0e10cSrcweir     Clip to set (can be empty)
117cdf0e10cSrcweir 
118cdf0e10cSrcweir     @param rCanvas
119cdf0e10cSrcweir     Canvas to create the clip polygon for
120cdf0e10cSrcweir 
121cdf0e10cSrcweir     @param rUserSize
122cdf0e10cSrcweir     The size of the view. Note that the returned clip will
123cdf0e10cSrcweir     <em>always</em> clip to at least the rect defined herein.
124cdf0e10cSrcweir 
125cdf0e10cSrcweir     @return the view clip polygon, in view coordinates, which is
126cdf0e10cSrcweir     guaranteed to at least clip to the view size.
127cdf0e10cSrcweir  */
createClipPolygon(const basegfx::B2DPolyPolygon & rClip,const cppcanvas::CanvasSharedPtr &,const basegfx::B2DSize & rUserSize)128cdf0e10cSrcweir basegfx::B2DPolyPolygon createClipPolygon( const basegfx::B2DPolyPolygon&    rClip,
129cdf0e10cSrcweir                                            const cppcanvas::CanvasSharedPtr& /*rCanvas*/,
130cdf0e10cSrcweir                                            const basegfx::B2DSize&           rUserSize )
131cdf0e10cSrcweir {
132cdf0e10cSrcweir     // setup canvas clipping
133cdf0e10cSrcweir     // =====================
134cdf0e10cSrcweir 
135cdf0e10cSrcweir     // AW: Simplified
136cdf0e10cSrcweir 	const basegfx::B2DRange aClipRange(0, 0, rUserSize.getX(), rUserSize.getY());
137cdf0e10cSrcweir 
138cdf0e10cSrcweir     if(rClip.count())
139cdf0e10cSrcweir     {
140cdf0e10cSrcweir     	return basegfx::tools::clipPolyPolygonOnRange(rClip, aClipRange, true, false);
141cdf0e10cSrcweir     }
142cdf0e10cSrcweir     else
143cdf0e10cSrcweir     {
144cdf0e10cSrcweir         return basegfx::B2DPolyPolygon(basegfx::tools::createPolygonFromRect(aClipRange));
145cdf0e10cSrcweir     }
146cdf0e10cSrcweir }
147cdf0e10cSrcweir 
148cdf0e10cSrcweir /** Prepare given clip polygon to be stored as the current clip
149cdf0e10cSrcweir 
150cdf0e10cSrcweir     Note that this is separate from createClipPolygon(), to allow
151cdf0e10cSrcweir     SlideView implementations to store this intermediate result
152cdf0e10cSrcweir     (createClipPolygon() has to be called every time the view size
153cdf0e10cSrcweir     changes)
154cdf0e10cSrcweir  */
prepareClip(const basegfx::B2DPolyPolygon & rClip)155*b06e87e7Smseidel basegfx::B2DPolyPolygon prepareClip( const basegfx::B2DPolyPolygon& rClip )
156cdf0e10cSrcweir {
157cdf0e10cSrcweir     basegfx::B2DPolyPolygon aClip( rClip );
158cdf0e10cSrcweir 
159cdf0e10cSrcweir     // TODO(P2): unnecessary, once XCanvas is correctly handling this
160cdf0e10cSrcweir     // AW: Should be no longer necessary; tools are now bezier-safe
161cdf0e10cSrcweir     if( aClip.areControlPointsUsed() )
162cdf0e10cSrcweir         aClip = basegfx::tools::adaptiveSubdivideByAngle( aClip );
163*b06e87e7Smseidel 
164cdf0e10cSrcweir     // normalize polygon, preparation for clipping
165cdf0e10cSrcweir     // in updateCanvas()
166cdf0e10cSrcweir     aClip = basegfx::tools::correctOrientations(aClip);
167cdf0e10cSrcweir     aClip = basegfx::tools::solveCrossovers(aClip);
168cdf0e10cSrcweir     aClip = basegfx::tools::stripNeutralPolygons(aClip);
169cdf0e10cSrcweir     aClip = basegfx::tools::stripDispensablePolygons(aClip, false);
170*b06e87e7Smseidel 
171cdf0e10cSrcweir     return aClip;
172cdf0e10cSrcweir }
173cdf0e10cSrcweir 
174cdf0e10cSrcweir 
clearRect(::cppcanvas::CanvasSharedPtr const & pCanvas,basegfx::B2IRange const & rArea)175cdf0e10cSrcweir void clearRect( ::cppcanvas::CanvasSharedPtr const& pCanvas,
176cdf0e10cSrcweir                 basegfx::B2IRange const&            rArea )
177cdf0e10cSrcweir {
178cdf0e10cSrcweir     // convert clip polygon to device coordinate system
179cdf0e10cSrcweir     ::basegfx::B2DPolyPolygon const* pClipPoly( pCanvas->getClip() );
180cdf0e10cSrcweir     if( pClipPoly )
181cdf0e10cSrcweir     {
182cdf0e10cSrcweir         ::basegfx::B2DPolyPolygon aClipPoly( *pClipPoly );
183cdf0e10cSrcweir         aClipPoly.transform( pCanvas->getTransformation() );
184cdf0e10cSrcweir         pCanvas->setClip( aClipPoly );
185cdf0e10cSrcweir     }
186cdf0e10cSrcweir 
187*b06e87e7Smseidel     // set transformation to identity (->device pixel)
188cdf0e10cSrcweir     pCanvas->setTransformation( ::basegfx::B2DHomMatrix() );
189cdf0e10cSrcweir 
190cdf0e10cSrcweir     // #i42440# Fill the _full_ background in
191cdf0e10cSrcweir     // black. Since we had to extend the bitmap by one
192cdf0e10cSrcweir     // pixel, and the bitmap is initialized white,
193cdf0e10cSrcweir     // depending on the slide content a one pixel wide
194cdf0e10cSrcweir     // line will show to the bottom and the right.
195cdf0e10cSrcweir     const ::basegfx::B2DPolygon aPoly(
196cdf0e10cSrcweir         ::basegfx::tools::createPolygonFromRect(
197cdf0e10cSrcweir             basegfx::B2DRange(rArea)));
198cdf0e10cSrcweir 
199*b06e87e7Smseidel     ::cppcanvas::PolyPolygonSharedPtr pPolyPoly(
200*b06e87e7Smseidel         ::cppcanvas::BaseGfxFactory::getInstance().createPolyPolygon( pCanvas,
201cdf0e10cSrcweir                                                                       aPoly ) );
202cdf0e10cSrcweir 
203cdf0e10cSrcweir     if( pPolyPoly )
204cdf0e10cSrcweir     {
205cdf0e10cSrcweir         pPolyPoly->setCompositeOp( cppcanvas::CanvasGraphic::SOURCE );
206cdf0e10cSrcweir         pPolyPoly->setRGBAFillColor( 0x00000000U );
207cdf0e10cSrcweir         pPolyPoly->draw();
208cdf0e10cSrcweir     }
209cdf0e10cSrcweir 
210cdf0e10cSrcweir #if defined(VERBOSE) && defined(DBG_UTIL)
211cdf0e10cSrcweir     ::cppcanvas::CanvasSharedPtr pCliplessCanvas( pCanvas->clone() );
212cdf0e10cSrcweir     pCliplessCanvas->setClip();
213cdf0e10cSrcweir 
214cdf0e10cSrcweir     if( pCanvas->getClip() )
215cdf0e10cSrcweir     {
216cdf0e10cSrcweir         ::cppcanvas::PolyPolygonSharedPtr pPolyPoly2(
217*b06e87e7Smseidel             ::cppcanvas::BaseGfxFactory::getInstance().createPolyPolygon( pCliplessCanvas,
218cdf0e10cSrcweir                                                                           *(pCanvas->getClip()) ));
219cdf0e10cSrcweir         if( pPolyPoly2 )
220cdf0e10cSrcweir         {
221cdf0e10cSrcweir             pPolyPoly2->setRGBALineColor( 0x008000FFU );
222cdf0e10cSrcweir             pPolyPoly2->draw();
223cdf0e10cSrcweir         }
224cdf0e10cSrcweir     }
225cdf0e10cSrcweir #endif
226cdf0e10cSrcweir }
227cdf0e10cSrcweir 
228cdf0e10cSrcweir /** Get bounds in pixel
229cdf0e10cSrcweir 
230cdf0e10cSrcweir     @param rLayerBounds
231cdf0e10cSrcweir     Bound rect, in user space coordinates
232cdf0e10cSrcweir 
233cdf0e10cSrcweir     @param rTransformation
234cdf0e10cSrcweir     User space to device pixel transformation
235cdf0e10cSrcweir 
236cdf0e10cSrcweir     @return the layer bounds in pixel, extended by one pixel to the
237cdf0e10cSrcweir     right and bottom
238cdf0e10cSrcweir  */
getLayerBoundsPixel(basegfx::B2DRange const & rLayerBounds,basegfx::B2DHomMatrix const & rTransformation)239cdf0e10cSrcweir basegfx::B2IRange getLayerBoundsPixel( basegfx::B2DRange const&     rLayerBounds,
240cdf0e10cSrcweir                                        basegfx::B2DHomMatrix const& rTransformation )
241cdf0e10cSrcweir {
242cdf0e10cSrcweir     ::basegfx::B2DRange aTmpRect;
243*b06e87e7Smseidel     ::canvas::tools::calcTransformedRectBounds( aTmpRect,
244*b06e87e7Smseidel                                                 rLayerBounds,
245cdf0e10cSrcweir                                                 rTransformation );
246cdf0e10cSrcweir 
247cdf0e10cSrcweir     if( aTmpRect.isEmpty() )
248cdf0e10cSrcweir         return ::basegfx::B2IRange();
249cdf0e10cSrcweir 
250*b06e87e7Smseidel     // #i42440# Returned layer size is one pixel too small, as
251*b06e87e7Smseidel     // rendering happens one pixel to the right and below the
252*b06e87e7Smseidel     // actual bound rect.
253cdf0e10cSrcweir     return ::basegfx::B2IRange( ::basegfx::fround(aTmpRect.getMinX()),
254cdf0e10cSrcweir                                 ::basegfx::fround(aTmpRect.getMinY()),
255cdf0e10cSrcweir                                 ::basegfx::fround(aTmpRect.getMaxX()) + 1,
256cdf0e10cSrcweir                                 ::basegfx::fround(aTmpRect.getMaxY()) + 1 );
257cdf0e10cSrcweir }
258cdf0e10cSrcweir 
259cdf0e10cSrcweir 
260cdf0e10cSrcweir // ----------------------------------------------------------------
261cdf0e10cSrcweir 
262cdf0e10cSrcweir /** Container class for sprites issued by a ViewLayer
263cdf0e10cSrcweir 
264cdf0e10cSrcweir     This class handles the sprite prioritization issues, that are
265cdf0e10cSrcweir     needed for layer sprites (e.g. the need to re-prioritize sprites
266cdf0e10cSrcweir     when the layer changes prio).
267cdf0e10cSrcweir  */
268cdf0e10cSrcweir class LayerSpriteContainer
269cdf0e10cSrcweir {
270cdf0e10cSrcweir     /** Max fill level of maSprites, before we try to prune it from
271cdf0e10cSrcweir         deceased sprites
272cdf0e10cSrcweir     */
273cdf0e10cSrcweir     enum{ SPRITE_ULLAGE=256 };
274cdf0e10cSrcweir 
275cdf0e10cSrcweir     /** All sprites that have been issued by this container (pruned
276cdf0e10cSrcweir         from time to time, for invalid references). This vector is
277cdf0e10cSrcweir         kept sorted with increasing sprite priority.
278cdf0e10cSrcweir     */
279cdf0e10cSrcweir     SpriteVector       maSprites;
280cdf0e10cSrcweir 
281*b06e87e7Smseidel     // Priority of this layer, relative to other view layers
282*b06e87e7Smseidel     basegfx::B1DRange maLayerPrioRange;
283cdf0e10cSrcweir 
getSpritePriority(std::size_t nSpriteNum) const284cdf0e10cSrcweir     double getSpritePriority( std::size_t nSpriteNum ) const
285cdf0e10cSrcweir     {
286cdf0e10cSrcweir         // divide the available layer range equally between all
287cdf0e10cSrcweir         // sprites, assign upper bound of individual sprite range as
288cdf0e10cSrcweir         // sprite prio (the layer itself gets assigned the lower bound
289cdf0e10cSrcweir         // of sprite 0's individual range):
290cdf0e10cSrcweir         //
291cdf0e10cSrcweir         // | layer 0                    | layer 1                    | ...
292cdf0e10cSrcweir         // |    sprite 0 |    sprite 1  |    sprite 0 |    sprite 1  | ...
293cdf0e10cSrcweir         return maLayerPrioRange.getMinimum() + maLayerPrioRange.getRange()*(nSpriteNum+1)/(maSprites.size()+1);
294cdf0e10cSrcweir     }
295cdf0e10cSrcweir 
296cdf0e10cSrcweir     /** Rescan sprite vector, and remove deceased sprites (and reset
297cdf0e10cSrcweir         sprite prio)
298cdf0e10cSrcweir 
299cdf0e10cSrcweir         @param aBegin
300cdf0e10cSrcweir         Iterator to the first entry to rescan
301cdf0e10cSrcweir      */
updateSprites()302cdf0e10cSrcweir     void updateSprites()
303cdf0e10cSrcweir     {
304cdf0e10cSrcweir         SpriteVector aValidSprites;
305cdf0e10cSrcweir 
306cdf0e10cSrcweir         // check all sprites for validity and set new priority
307cdf0e10cSrcweir         SpriteVector::iterator       aCurrSprite( maSprites.begin() );
308cdf0e10cSrcweir         const SpriteVector::iterator aEnd( maSprites.end() );
309cdf0e10cSrcweir         while( aCurrSprite != aEnd )
310cdf0e10cSrcweir         {
311cdf0e10cSrcweir             cppcanvas::CustomSpriteSharedPtr pCurrSprite( aCurrSprite->mpSprite.lock() );
312*b06e87e7Smseidel 
313cdf0e10cSrcweir             if( pCurrSprite )
314cdf0e10cSrcweir             {
315cdf0e10cSrcweir                 // only copy still valid sprites over to the refreshed
316cdf0e10cSrcweir                 // sprite vector.
317cdf0e10cSrcweir                 aValidSprites.push_back( *aCurrSprite );
318cdf0e10cSrcweir 
319*b06e87e7Smseidel                 pCurrSprite->setPriority(
320cdf0e10cSrcweir                     getSpritePriority( aValidSprites.size()-1 ));
321cdf0e10cSrcweir             }
322cdf0e10cSrcweir 
323cdf0e10cSrcweir             ++aCurrSprite;
324cdf0e10cSrcweir         }
325cdf0e10cSrcweir 
326cdf0e10cSrcweir         // replace sprite list with pruned one
327cdf0e10cSrcweir         maSprites.swap( aValidSprites );
328cdf0e10cSrcweir     }
329cdf0e10cSrcweir 
330cdf0e10cSrcweir public:
LayerSpriteContainer()331cdf0e10cSrcweir     LayerSpriteContainer() :
332cdf0e10cSrcweir         maSprites(),
333cdf0e10cSrcweir         maLayerPrioRange()
334cdf0e10cSrcweir     {
335cdf0e10cSrcweir     }
336cdf0e10cSrcweir 
getLayerPriority() const337cdf0e10cSrcweir     basegfx::B1DRange getLayerPriority() const
338cdf0e10cSrcweir     {
339cdf0e10cSrcweir         return maLayerPrioRange;
340cdf0e10cSrcweir     }
341cdf0e10cSrcweir 
setLayerPriority(const basegfx::B1DRange & rRange)342cdf0e10cSrcweir     void setLayerPriority( const basegfx::B1DRange& rRange )
343cdf0e10cSrcweir     {
344cdf0e10cSrcweir         if( rRange != maLayerPrioRange )
345cdf0e10cSrcweir         {
346cdf0e10cSrcweir             maLayerPrioRange = rRange;
347cdf0e10cSrcweir 
348cdf0e10cSrcweir             // prune and recalc sprite prios
349cdf0e10cSrcweir             updateSprites();
350cdf0e10cSrcweir         }
351cdf0e10cSrcweir     }
352cdf0e10cSrcweir 
addSprite(const cppcanvas::CustomSpriteSharedPtr & pSprite,double nPriority)353cdf0e10cSrcweir     void addSprite( const cppcanvas::CustomSpriteSharedPtr& pSprite,
354cdf0e10cSrcweir                     double                                  nPriority )
355cdf0e10cSrcweir     {
356cdf0e10cSrcweir         if( !pSprite )
357cdf0e10cSrcweir             return;
358cdf0e10cSrcweir 
359cdf0e10cSrcweir         SpriteEntry aEntry( pSprite,nPriority );
360cdf0e10cSrcweir 
361cdf0e10cSrcweir         // insert new sprite, such that vector stays sorted
362cdf0e10cSrcweir         SpriteVector::iterator aInsertPos(
363cdf0e10cSrcweir             maSprites.insert(
364cdf0e10cSrcweir                 std::lower_bound( maSprites.begin(),
365cdf0e10cSrcweir                                   maSprites.end(),
366cdf0e10cSrcweir                                   aEntry ),
367cdf0e10cSrcweir                 aEntry ));
368cdf0e10cSrcweir 
369cdf0e10cSrcweir         const std::size_t nNumSprites( maSprites.size() );
370cdf0e10cSrcweir         if( nNumSprites > SPRITE_ULLAGE ||
371cdf0e10cSrcweir             maSprites.end() - aInsertPos > 1 )
372cdf0e10cSrcweir         {
373cdf0e10cSrcweir             // updateSprites() also updates all sprite prios
374cdf0e10cSrcweir             updateSprites();
375cdf0e10cSrcweir         }
376cdf0e10cSrcweir         else
377cdf0e10cSrcweir         {
378cdf0e10cSrcweir             // added sprite to the end, and not too many sprites in
379cdf0e10cSrcweir             // vector - perform optimized update (only need to set
380cdf0e10cSrcweir             // prio). This basically caters for the common case of
381cdf0e10cSrcweir             // iterated character animations, which generate lots of
382cdf0e10cSrcweir             // sprites, all added to the end.
383*b06e87e7Smseidel             pSprite->setPriority(
384cdf0e10cSrcweir                 getSpritePriority( nNumSprites-1 ));
385cdf0e10cSrcweir         }
386cdf0e10cSrcweir     }
387cdf0e10cSrcweir 
clear()388cdf0e10cSrcweir     void clear()
389cdf0e10cSrcweir     {
390cdf0e10cSrcweir         maSprites.clear();
391cdf0e10cSrcweir     }
392cdf0e10cSrcweir };
393cdf0e10cSrcweir 
394cdf0e10cSrcweir 
395cdf0e10cSrcweir // ----------------------------------------------------------------
396cdf0e10cSrcweir 
397cdf0e10cSrcweir 
398cdf0e10cSrcweir /** This class provides layers for a slide view
399cdf0e10cSrcweir 
400cdf0e10cSrcweir     Layers are used to render animations with the correct z order -
401cdf0e10cSrcweir     because sprites are always in front of the static canvas
402cdf0e10cSrcweir     background, shapes that must appear <em<before</em> an animation
403cdf0e10cSrcweir     must also be displayed as a sprite.
404cdf0e10cSrcweir 
405cdf0e10cSrcweir     Each layer has a priority assigned to it (valid range [0,1]), which
406cdf0e10cSrcweir     also affects all sprites created for this specific layer - i.e. if
407cdf0e10cSrcweir     the layer priority changes, the sprites change z order together
408cdf0e10cSrcweir     with their parent.
409cdf0e10cSrcweir  */
410*b06e87e7Smseidel class SlideViewLayer : public ViewLayer,
411cdf0e10cSrcweir                        private boost::noncopyable
412cdf0e10cSrcweir {
413*b06e87e7Smseidel     // Smart container for all sprites issued by this layer
414cdf0e10cSrcweir     mutable LayerSpriteContainer             maSpriteContainer;
415cdf0e10cSrcweir 
416*b06e87e7Smseidel     // Bounds of this layer in user space coordinates
417cdf0e10cSrcweir     basegfx::B2DRange                        maLayerBounds;
418cdf0e10cSrcweir 
419*b06e87e7Smseidel     // Bounds of this layer in device pixel
420cdf0e10cSrcweir     mutable basegfx::B2IRange                maLayerBoundsPixel;
421cdf0e10cSrcweir 
422*b06e87e7Smseidel     // Current clip polygon in user coordinates
423cdf0e10cSrcweir     basegfx::B2DPolyPolygon                  maClip;
424*b06e87e7Smseidel 
425*b06e87e7Smseidel     // Current size of the view in user coordinates
426cdf0e10cSrcweir     basegfx::B2DSize                         maUserSize;
427cdf0e10cSrcweir 
428*b06e87e7Smseidel     // Current overall view transformation
429cdf0e10cSrcweir     basegfx::B2DHomMatrix                    maTransformation;
430cdf0e10cSrcweir 
431*b06e87e7Smseidel     // 'parent' canvas, this viewlayer is associated with
432cdf0e10cSrcweir     const cppcanvas::SpriteCanvasSharedPtr   mpSpriteCanvas;
433cdf0e10cSrcweir 
434cdf0e10cSrcweir     /** output surface (necessarily a sprite, won't otherwise be able
435cdf0e10cSrcweir         to display anything <em>before</em> other sprites)
436cdf0e10cSrcweir     */
437cdf0e10cSrcweir     mutable cppcanvas::CustomSpriteSharedPtr mpSprite;
438cdf0e10cSrcweir 
439*b06e87e7Smseidel     // actual output canvas retrieved from a sprite
440cdf0e10cSrcweir     mutable cppcanvas::CanvasSharedPtr       mpOutputCanvas;
441*b06e87e7Smseidel 
442*b06e87e7Smseidel     // ptr back to owning view. needed for isOnView() method
443cdf0e10cSrcweir     View const* const                        mpParentView;
444cdf0e10cSrcweir 
445cdf0e10cSrcweir public:
446cdf0e10cSrcweir     /** Create a new layer
447cdf0e10cSrcweir 
448cdf0e10cSrcweir         @param pCanvas
449cdf0e10cSrcweir         Sprite canvas to create the layer on
450cdf0e10cSrcweir 
451cdf0e10cSrcweir         @param rTransform
452cdf0e10cSrcweir         Initial overall canvas transformation
453cdf0e10cSrcweir 
454cdf0e10cSrcweir         @param rLayerBounds
455cdf0e10cSrcweir         Initial layer bounds, in view coordinate system
456cdf0e10cSrcweir      */
SlideViewLayer(const cppcanvas::SpriteCanvasSharedPtr & pCanvas,const basegfx::B2DHomMatrix & rTransform,const basegfx::B2DRange & rLayerBounds,const basegfx::B2DSize & rUserSize,View const * const pParentView)457cdf0e10cSrcweir     SlideViewLayer( const cppcanvas::SpriteCanvasSharedPtr& pCanvas,
458cdf0e10cSrcweir                     const basegfx::B2DHomMatrix&            rTransform,
459cdf0e10cSrcweir                     const basegfx::B2DRange&                rLayerBounds,
460cdf0e10cSrcweir                     const basegfx::B2DSize&                 rUserSize,
461cdf0e10cSrcweir                     View const* const                       pParentView) :
462cdf0e10cSrcweir         maSpriteContainer(),
463cdf0e10cSrcweir         maLayerBounds(rLayerBounds),
464cdf0e10cSrcweir         maLayerBoundsPixel(),
465cdf0e10cSrcweir         maClip(),
466cdf0e10cSrcweir         maUserSize(rUserSize),
467cdf0e10cSrcweir         maTransformation(rTransform),
468cdf0e10cSrcweir         mpSpriteCanvas(pCanvas),
469cdf0e10cSrcweir         mpSprite(),
470cdf0e10cSrcweir         mpOutputCanvas(),
471cdf0e10cSrcweir         mpParentView(pParentView)
472*b06e87e7Smseidel     {
473cdf0e10cSrcweir     }
474cdf0e10cSrcweir 
updateView(const basegfx::B2DHomMatrix & rMatrix,const basegfx::B2DSize & rUserSize)475cdf0e10cSrcweir     void updateView( const basegfx::B2DHomMatrix& rMatrix,
476cdf0e10cSrcweir                      const basegfx::B2DSize&      rUserSize )
477cdf0e10cSrcweir     {
478cdf0e10cSrcweir         maTransformation = rMatrix;
479cdf0e10cSrcweir         maUserSize = rUserSize;
480cdf0e10cSrcweir 
481cdf0e10cSrcweir         // limit layer bounds to visible screen
482cdf0e10cSrcweir         maLayerBounds.intersect( basegfx::B2DRange(0.0,
483cdf0e10cSrcweir                                                    0.0,
484cdf0e10cSrcweir                                                    maUserSize.getX(),
485cdf0e10cSrcweir                                                    maUserSize.getY()) );
486cdf0e10cSrcweir 
487cdf0e10cSrcweir         basegfx::B2IRange const& rNewLayerPixel(
488cdf0e10cSrcweir             getLayerBoundsPixel(maLayerBounds,
489cdf0e10cSrcweir                                 maTransformation) );
490cdf0e10cSrcweir         if( rNewLayerPixel != maLayerBoundsPixel )
491cdf0e10cSrcweir         {
492cdf0e10cSrcweir             // re-gen sprite with new size
493cdf0e10cSrcweir             mpOutputCanvas.reset();
494cdf0e10cSrcweir             mpSprite.reset();
495cdf0e10cSrcweir         }
496cdf0e10cSrcweir     }
497cdf0e10cSrcweir 
498cdf0e10cSrcweir private:
499cdf0e10cSrcweir     // ViewLayer interface
500cdf0e10cSrcweir     // ----------------------------------------------
501cdf0e10cSrcweir 
createSprite(const::basegfx::B2DSize & rSpriteSizePixel,double nPriority) const502cdf0e10cSrcweir     virtual cppcanvas::CustomSpriteSharedPtr createSprite(
503cdf0e10cSrcweir         const ::basegfx::B2DSize& rSpriteSizePixel,
504cdf0e10cSrcweir         double                    nPriority ) const
505cdf0e10cSrcweir     {
506cdf0e10cSrcweir         cppcanvas::CustomSpriteSharedPtr pSprite(
507cdf0e10cSrcweir             mpSpriteCanvas->createCustomSprite( rSpriteSizePixel ) );
508cdf0e10cSrcweir 
509cdf0e10cSrcweir         maSpriteContainer.addSprite( pSprite,
510cdf0e10cSrcweir                                      nPriority );
511cdf0e10cSrcweir 
512cdf0e10cSrcweir         return pSprite;
513cdf0e10cSrcweir     }
514cdf0e10cSrcweir 
setPriority(const basegfx::B1DRange & rRange)515cdf0e10cSrcweir     virtual void setPriority( const basegfx::B1DRange& rRange )
516cdf0e10cSrcweir     {
517cdf0e10cSrcweir         OSL_ENSURE( !rRange.isEmpty() &&
518cdf0e10cSrcweir                     rRange.getMinimum() >= 1.0,
519cdf0e10cSrcweir                     "SlideViewLayer::setPriority(): prio MUST be larger than 1.0 (because "
520cdf0e10cSrcweir                     "the background layer already lies there)" );
521cdf0e10cSrcweir 
522cdf0e10cSrcweir         maSpriteContainer.setLayerPriority( rRange );
523cdf0e10cSrcweir 
524cdf0e10cSrcweir         if( mpSprite )
525cdf0e10cSrcweir             mpSprite->setPriority( rRange.getMinimum() );
526cdf0e10cSrcweir     }
527cdf0e10cSrcweir 
getTransformation() const528cdf0e10cSrcweir     virtual basegfx::B2DHomMatrix getTransformation() const
529cdf0e10cSrcweir     {
530cdf0e10cSrcweir         // Offset given transformation by left, top border of given
531cdf0e10cSrcweir         // range (after transformation through given transformation)
532cdf0e10cSrcweir         basegfx::B2DRectangle aTmpRect;
533*b06e87e7Smseidel         canvas::tools::calcTransformedRectBounds( aTmpRect,
534*b06e87e7Smseidel                                                   maLayerBounds,
535cdf0e10cSrcweir                                                   maTransformation );
536cdf0e10cSrcweir 
537cdf0e10cSrcweir         basegfx::B2DHomMatrix aMatrix( maTransformation );
538cdf0e10cSrcweir 
539*b06e87e7Smseidel         // Add translation according to the origin of aTmpRect. Ignore the
540cdf0e10cSrcweir         // translation when aTmpRect was not properly initialized.
541cdf0e10cSrcweir         if ( ! aTmpRect.isEmpty())
542cdf0e10cSrcweir         {
543cdf0e10cSrcweir             aMatrix.translate( -basegfx::fround(aTmpRect.getMinX()),
544cdf0e10cSrcweir                                -basegfx::fround(aTmpRect.getMinY()) );
545cdf0e10cSrcweir         }
546cdf0e10cSrcweir 
547cdf0e10cSrcweir         return aMatrix;
548cdf0e10cSrcweir     }
549cdf0e10cSrcweir 
getSpriteTransformation() const550cdf0e10cSrcweir     virtual basegfx::B2DHomMatrix getSpriteTransformation() const
551cdf0e10cSrcweir     {
552cdf0e10cSrcweir         return maTransformation;
553cdf0e10cSrcweir     }
554cdf0e10cSrcweir 
clear() const555cdf0e10cSrcweir     virtual void clear() const
556cdf0e10cSrcweir     {
557cdf0e10cSrcweir         // keep layer clip
558cdf0e10cSrcweir         clearRect(getCanvas()->clone(),
559cdf0e10cSrcweir                   maLayerBoundsPixel);
560cdf0e10cSrcweir     }
561cdf0e10cSrcweir 
clearAll() const562cdf0e10cSrcweir     virtual void clearAll() const
563cdf0e10cSrcweir     {
564cdf0e10cSrcweir         ::cppcanvas::CanvasSharedPtr pCanvas( getCanvas()->clone() );
565cdf0e10cSrcweir 
566cdf0e10cSrcweir         // clear layer clip, to clear whole area
567cdf0e10cSrcweir         pCanvas->setClip();
568cdf0e10cSrcweir 
569cdf0e10cSrcweir         clearRect(pCanvas,
570cdf0e10cSrcweir                   maLayerBoundsPixel);
571cdf0e10cSrcweir     }
572cdf0e10cSrcweir 
isOnView(boost::shared_ptr<View> const & rView) const573cdf0e10cSrcweir     virtual bool isOnView(boost::shared_ptr<View> const& rView) const
574cdf0e10cSrcweir     {
575cdf0e10cSrcweir         return rView.get() == mpParentView;
576cdf0e10cSrcweir     }
577cdf0e10cSrcweir 
getCanvas() const578cdf0e10cSrcweir     virtual cppcanvas::CanvasSharedPtr getCanvas() const
579cdf0e10cSrcweir     {
580cdf0e10cSrcweir         if( !mpOutputCanvas )
581cdf0e10cSrcweir         {
582cdf0e10cSrcweir             if( !mpSprite )
583cdf0e10cSrcweir             {
584cdf0e10cSrcweir                 maLayerBoundsPixel = getLayerBoundsPixel(maLayerBounds,
585cdf0e10cSrcweir                                                          maTransformation);
586cdf0e10cSrcweir 
587cdf0e10cSrcweir                 // HACK: ensure at least 1x1 pixel size. clients might
588cdf0e10cSrcweir                 // need an actual canvas (e.g. for bound rect
589cdf0e10cSrcweir                 // calculations) without rendering anything. Better
590cdf0e10cSrcweir                 // solution: introduce something like a reference
591cdf0e10cSrcweir                 // canvas for ViewLayers, which is always available.
592cdf0e10cSrcweir                 if( maLayerBoundsPixel.isEmpty() )
593cdf0e10cSrcweir                     maLayerBoundsPixel = basegfx::B2IRange(0,0,1,1);
594cdf0e10cSrcweir 
595cdf0e10cSrcweir                 const basegfx::B2I64Tuple& rSpriteSize(maLayerBoundsPixel.getRange());
596cdf0e10cSrcweir                 mpSprite = mpSpriteCanvas->createCustomSprite(
597cdf0e10cSrcweir                     basegfx::B2DVector(sal::static_int_cast<sal_Int32>(rSpriteSize.getX()),
598cdf0e10cSrcweir                                        sal::static_int_cast<sal_Int32>(rSpriteSize.getY())) );
599cdf0e10cSrcweir 
600*b06e87e7Smseidel                 mpSprite->setPriority(
601cdf0e10cSrcweir                     maSpriteContainer.getLayerPriority().getMinimum() );
602cdf0e10cSrcweir 
603cdf0e10cSrcweir #if defined(VERBOSE) && defined(DBG_UTIL)
604*b06e87e7Smseidel                 mpSprite->movePixel(
605*b06e87e7Smseidel                     basegfx::B2DPoint(maLayerBoundsPixel.getMinimum()) +
606cdf0e10cSrcweir                     basegfx::B2DPoint(10,10) );
607cdf0e10cSrcweir 
608*b06e87e7Smseidel                 mpSprite->setAlpha(0.5);
609cdf0e10cSrcweir #else
610*b06e87e7Smseidel                 mpSprite->movePixel(
611cdf0e10cSrcweir                     basegfx::B2DPoint(maLayerBoundsPixel.getMinimum()) );
612cdf0e10cSrcweir 
613*b06e87e7Smseidel                 mpSprite->setAlpha(1.0);
614cdf0e10cSrcweir #endif
615*b06e87e7Smseidel                 mpSprite->show();
616cdf0e10cSrcweir             }
617cdf0e10cSrcweir 
618cdf0e10cSrcweir             ENSURE_OR_THROW( mpSprite,
619cdf0e10cSrcweir                               "SlideViewLayer::getCanvas(): no layer sprite" );
620cdf0e10cSrcweir 
621cdf0e10cSrcweir             mpOutputCanvas = mpSprite->getContentCanvas();
622*b06e87e7Smseidel 
623cdf0e10cSrcweir             ENSURE_OR_THROW( mpOutputCanvas,
624cdf0e10cSrcweir                               "SlideViewLayer::getCanvas(): sprite doesn't yield a canvas" );
625cdf0e10cSrcweir 
626cdf0e10cSrcweir             // new canvas retrieved - setup transformation and clip
627cdf0e10cSrcweir             mpOutputCanvas->setTransformation( getTransformation() );
628*b06e87e7Smseidel             mpOutputCanvas->setClip(
629cdf0e10cSrcweir                 createClipPolygon( maClip,
630cdf0e10cSrcweir                                    mpOutputCanvas,
631cdf0e10cSrcweir                                    maUserSize ));
632cdf0e10cSrcweir         }
633*b06e87e7Smseidel 
634cdf0e10cSrcweir         return mpOutputCanvas;
635cdf0e10cSrcweir     }
636cdf0e10cSrcweir 
setClip(const basegfx::B2DPolyPolygon & rClip)637cdf0e10cSrcweir     virtual void setClip( const basegfx::B2DPolyPolygon& rClip )
638cdf0e10cSrcweir     {
639cdf0e10cSrcweir         basegfx::B2DPolyPolygon aNewClip = prepareClip( rClip );
640cdf0e10cSrcweir 
641cdf0e10cSrcweir         if( aNewClip != maClip )
642cdf0e10cSrcweir         {
643cdf0e10cSrcweir             maClip = aNewClip;
644cdf0e10cSrcweir 
645cdf0e10cSrcweir             if(mpOutputCanvas )
646*b06e87e7Smseidel                 mpOutputCanvas->setClip(
647cdf0e10cSrcweir                     createClipPolygon( maClip,
648cdf0e10cSrcweir                                        mpOutputCanvas,
649cdf0e10cSrcweir                                        maUserSize ));
650cdf0e10cSrcweir         }
651cdf0e10cSrcweir     }
652cdf0e10cSrcweir 
resize(const::basegfx::B2DRange & rArea)653cdf0e10cSrcweir     virtual bool resize( const ::basegfx::B2DRange& rArea )
654cdf0e10cSrcweir     {
655cdf0e10cSrcweir         const bool bRet( maLayerBounds != rArea );
656cdf0e10cSrcweir         maLayerBounds = rArea;
657cdf0e10cSrcweir         updateView( maTransformation,
658cdf0e10cSrcweir                     maUserSize );
659cdf0e10cSrcweir 
660cdf0e10cSrcweir         return bRet;
661cdf0e10cSrcweir     }
662cdf0e10cSrcweir };
663cdf0e10cSrcweir 
664cdf0e10cSrcweir 
665cdf0e10cSrcweir // ---------------------------------------------------------
666cdf0e10cSrcweir 
667cdf0e10cSrcweir typedef cppu::WeakComponentImplHelper2<
668*b06e87e7Smseidel     ::com::sun::star::util::XModifyListener,
669cdf0e10cSrcweir       ::com::sun::star::awt::XPaintListener> SlideViewBase;
670cdf0e10cSrcweir 
671cdf0e10cSrcweir /** SlideView class
672cdf0e10cSrcweir 
673cdf0e10cSrcweir     This class implements the View interface, encapsulating
674cdf0e10cSrcweir     <em>one</em> view a slideshow is displayed on.
675cdf0e10cSrcweir  */
676cdf0e10cSrcweir class SlideView : private cppu::BaseMutex,
677cdf0e10cSrcweir                   public SlideViewBase,
678cdf0e10cSrcweir                   public UnoView
679cdf0e10cSrcweir {
680cdf0e10cSrcweir public:
681cdf0e10cSrcweir     SlideView( const uno::Reference<presentation::XSlideShowView>& xView,
682cdf0e10cSrcweir                EventQueue&                                         rEventQueue,
683cdf0e10cSrcweir                EventMultiplexer&                                   rEventMultiplexer );
684cdf0e10cSrcweir     void updateCanvas();
685cdf0e10cSrcweir 
686cdf0e10cSrcweir private:
687cdf0e10cSrcweir     // View:
688cdf0e10cSrcweir     virtual ViewLayerSharedPtr createViewLayer( const basegfx::B2DRange& rLayerBounds ) const;
689cdf0e10cSrcweir     virtual bool updateScreen() const;
690cdf0e10cSrcweir     virtual bool paintScreen() const;
691cdf0e10cSrcweir     virtual void setViewSize( const ::basegfx::B2DSize& );
692cdf0e10cSrcweir     virtual void setCursorShape( sal_Int16 nPointerShape );
693cdf0e10cSrcweir 
694cdf0e10cSrcweir     // ViewLayer interface
695cdf0e10cSrcweir     virtual bool isOnView(boost::shared_ptr<View> const& rView) const;
696cdf0e10cSrcweir     virtual void clear() const;
697cdf0e10cSrcweir     virtual void clearAll() const;
698cdf0e10cSrcweir     virtual cppcanvas::CanvasSharedPtr getCanvas() const;
699cdf0e10cSrcweir     virtual cppcanvas::CustomSpriteSharedPtr createSprite( const ::basegfx::B2DSize& rSpriteSizePixel,
700cdf0e10cSrcweir                                                            double                    nPriority ) const;
701cdf0e10cSrcweir     virtual void setPriority( const basegfx::B1DRange& rRange );
702cdf0e10cSrcweir     virtual ::basegfx::B2DHomMatrix getTransformation() const;
703cdf0e10cSrcweir     virtual basegfx::B2DHomMatrix getSpriteTransformation() const;
704cdf0e10cSrcweir     virtual void setClip( const ::basegfx::B2DPolyPolygon& rClip );
705cdf0e10cSrcweir     virtual bool resize( const ::basegfx::B2DRange& rArea );
706cdf0e10cSrcweir 
707cdf0e10cSrcweir     // UnoView:
708cdf0e10cSrcweir     virtual void _dispose();
709cdf0e10cSrcweir     virtual uno::Reference<presentation::XSlideShowView> getUnoView()const;
710cdf0e10cSrcweir     virtual void setIsSoundEnabled (const bool bValue);
711cdf0e10cSrcweir     virtual bool isSoundEnabled (void) const;
712cdf0e10cSrcweir 
713cdf0e10cSrcweir     // XEventListener:
714cdf0e10cSrcweir     virtual void SAL_CALL disposing( lang::EventObject const& evt )
715cdf0e10cSrcweir         throw (uno::RuntimeException);
716cdf0e10cSrcweir     // XModifyListener:
717cdf0e10cSrcweir     virtual void SAL_CALL modified( const lang::EventObject& aEvent )
718cdf0e10cSrcweir         throw (uno::RuntimeException);
719cdf0e10cSrcweir     // XPaintListener:
720cdf0e10cSrcweir     virtual void SAL_CALL windowPaint( const awt::PaintEvent& e )
721cdf0e10cSrcweir         throw (uno::RuntimeException);
722cdf0e10cSrcweir 
723cdf0e10cSrcweir     // WeakComponentImplHelperBase:
724cdf0e10cSrcweir     virtual void SAL_CALL disposing();
725cdf0e10cSrcweir 
726cdf0e10cSrcweir     void updateClip();
727cdf0e10cSrcweir 
728*b06e87e7Smseidel private:
729cdf0e10cSrcweir     typedef std::vector< boost::weak_ptr<SlideViewLayer> > ViewLayerVector;
730cdf0e10cSrcweir 
731*b06e87e7Smseidel     // Prune viewlayers from deceased ones, optionally update them
732cdf0e10cSrcweir     void pruneLayers( bool bWithViewLayerUpdate=false ) const;
733cdf0e10cSrcweir 
734cdf0e10cSrcweir     /** Max fill level of maViewLayers, before we try to prune it from
735cdf0e10cSrcweir         deceased layers
736cdf0e10cSrcweir     */
737cdf0e10cSrcweir     enum{ LAYER_ULLAGE=8 };
738cdf0e10cSrcweir 
739cdf0e10cSrcweir     uno::Reference<presentation::XSlideShowView>              mxView;
740cdf0e10cSrcweir     cppcanvas::SpriteCanvasSharedPtr                          mpCanvas;
741*b06e87e7Smseidel 
742cdf0e10cSrcweir     EventMultiplexer&                                         mrEventMultiplexer;
743cdf0e10cSrcweir     EventQueue&                                               mrEventQueue;
744cdf0e10cSrcweir 
745cdf0e10cSrcweir     mutable LayerSpriteContainer                              maSprites;
746*b06e87e7Smseidel     mutable ViewLayerVector                                   maViewLayers;
747cdf0e10cSrcweir 
748cdf0e10cSrcweir     basegfx::B2DPolyPolygon                                   maClip;
749*b06e87e7Smseidel 
750cdf0e10cSrcweir     basegfx::B2DHomMatrix                                     maViewTransform;
751cdf0e10cSrcweir     basegfx::B2DSize                                          maUserSize;
752cdf0e10cSrcweir     bool mbIsSoundEnabled;
753cdf0e10cSrcweir };
754cdf0e10cSrcweir 
755cdf0e10cSrcweir 
SlideView(const uno::Reference<presentation::XSlideShowView> & xView,EventQueue & rEventQueue,EventMultiplexer & rEventMultiplexer)756cdf0e10cSrcweir SlideView::SlideView( const uno::Reference<presentation::XSlideShowView>& xView,
757cdf0e10cSrcweir                       EventQueue&                                         rEventQueue,
758cdf0e10cSrcweir                       EventMultiplexer&                                   rEventMultiplexer ) :
759cdf0e10cSrcweir     SlideViewBase( m_aMutex ),
760cdf0e10cSrcweir     mxView( xView ),
761cdf0e10cSrcweir     mpCanvas(),
762cdf0e10cSrcweir     mrEventMultiplexer( rEventMultiplexer ),
763cdf0e10cSrcweir     mrEventQueue( rEventQueue ),
764cdf0e10cSrcweir     maSprites(),
765cdf0e10cSrcweir     maViewLayers(),
766cdf0e10cSrcweir     maClip(),
767cdf0e10cSrcweir     maViewTransform(),
768*b06e87e7Smseidel     maUserSize( 1.0, 1.0 ), // default size: one-by-one rectangle
769cdf0e10cSrcweir     mbIsSoundEnabled(true)
770cdf0e10cSrcweir {
771cdf0e10cSrcweir     // take care not constructing any UNO references to this _inside_
772*b06e87e7Smseidel     // ctor, shift that code to createSlideView()!
773cdf0e10cSrcweir     ENSURE_OR_THROW( mxView.is(),
774cdf0e10cSrcweir                       "SlideView::SlideView(): Invalid view" );
775*b06e87e7Smseidel 
776cdf0e10cSrcweir     mpCanvas = cppcanvas::VCLFactory::getInstance().createSpriteCanvas(
777cdf0e10cSrcweir         xView->getCanvas() );
778*b06e87e7Smseidel     ENSURE_OR_THROW( mpCanvas,
779cdf0e10cSrcweir                       "Could not create cppcanvas" );
780*b06e87e7Smseidel 
781cdf0e10cSrcweir     geometry::AffineMatrix2D aViewTransform(
782cdf0e10cSrcweir         xView->getTransformation() );
783cdf0e10cSrcweir 
784cdf0e10cSrcweir     if( basegfx::fTools::equalZero(
785cdf0e10cSrcweir             basegfx::B2DVector(aViewTransform.m00,
786cdf0e10cSrcweir                                aViewTransform.m10).getLength()) ||
787cdf0e10cSrcweir         basegfx::fTools::equalZero(
788cdf0e10cSrcweir             basegfx::B2DVector(aViewTransform.m01,
789cdf0e10cSrcweir                                aViewTransform.m11).getLength()) )
790cdf0e10cSrcweir     {
791*b06e87e7Smseidel         OSL_ENSURE( false,
792cdf0e10cSrcweir                     "SlideView::SlideView(): Singular matrix!" );
793cdf0e10cSrcweir 
794cdf0e10cSrcweir         canvas::tools::setIdentityAffineMatrix2D(aViewTransform);
795cdf0e10cSrcweir     }
796*b06e87e7Smseidel 
797cdf0e10cSrcweir     basegfx::unotools::homMatrixFromAffineMatrix(
798cdf0e10cSrcweir         maViewTransform, aViewTransform );
799cdf0e10cSrcweir 
800cdf0e10cSrcweir     // once and forever: set fixed prio to this 'layer' (we're always
801cdf0e10cSrcweir     // the background layer)
802cdf0e10cSrcweir     maSprites.setLayerPriority( basegfx::B1DRange(0.0,1.0) );
803cdf0e10cSrcweir }
804cdf0e10cSrcweir 
disposing()805cdf0e10cSrcweir void SlideView::disposing()
806cdf0e10cSrcweir {
807cdf0e10cSrcweir     osl::MutexGuard aGuard( m_aMutex );
808cdf0e10cSrcweir 
809cdf0e10cSrcweir     maViewLayers.clear();
810cdf0e10cSrcweir     maSprites.clear();
811cdf0e10cSrcweir     mpCanvas.reset();
812cdf0e10cSrcweir 
813cdf0e10cSrcweir     // additionally, also de-register from XSlideShowView
814*b06e87e7Smseidel     if (mxView.is())
815cdf0e10cSrcweir     {
816cdf0e10cSrcweir         mxView->removeTransformationChangedListener( this );
817cdf0e10cSrcweir         mxView->removePaintListener( this );
818cdf0e10cSrcweir         mxView.clear();
819cdf0e10cSrcweir     }
820cdf0e10cSrcweir }
821cdf0e10cSrcweir 
createViewLayer(const basegfx::B2DRange & rLayerBounds) const822cdf0e10cSrcweir ViewLayerSharedPtr SlideView::createViewLayer( const basegfx::B2DRange& rLayerBounds ) const
823cdf0e10cSrcweir {
824cdf0e10cSrcweir     osl::MutexGuard aGuard( m_aMutex );
825cdf0e10cSrcweir 
826*b06e87e7Smseidel     ENSURE_OR_THROW( mpCanvas,
827cdf0e10cSrcweir                       "SlideView::createViewLayer(): Disposed" );
828cdf0e10cSrcweir 
829cdf0e10cSrcweir     const std::size_t nNumLayers( maViewLayers.size() );
830cdf0e10cSrcweir 
831cdf0e10cSrcweir     // avoid filling up layer vector with lots of deceased layer weak
832cdf0e10cSrcweir     // ptrs
833cdf0e10cSrcweir     if( nNumLayers > LAYER_ULLAGE )
834cdf0e10cSrcweir         pruneLayers();
835cdf0e10cSrcweir 
836cdf0e10cSrcweir     boost::shared_ptr<SlideViewLayer> pViewLayer( new SlideViewLayer(mpCanvas,
837cdf0e10cSrcweir                                                                      getTransformation(),
838cdf0e10cSrcweir                                                                      rLayerBounds,
839cdf0e10cSrcweir                                                                      maUserSize,
840cdf0e10cSrcweir                                                                      this) );
841cdf0e10cSrcweir     maViewLayers.push_back( pViewLayer );
842cdf0e10cSrcweir 
843cdf0e10cSrcweir     return pViewLayer;
844cdf0e10cSrcweir }
845cdf0e10cSrcweir 
updateScreen() const846cdf0e10cSrcweir bool SlideView::updateScreen() const
847cdf0e10cSrcweir {
848cdf0e10cSrcweir     osl::MutexGuard aGuard( m_aMutex );
849cdf0e10cSrcweir 
850cdf0e10cSrcweir     ENSURE_OR_RETURN_FALSE( mpCanvas.get(),
851cdf0e10cSrcweir                        "SlideView::updateScreen(): Disposed" );
852cdf0e10cSrcweir 
853cdf0e10cSrcweir     return mpCanvas->updateScreen( false );
854cdf0e10cSrcweir }
855cdf0e10cSrcweir 
paintScreen() const856cdf0e10cSrcweir bool SlideView::paintScreen() const
857cdf0e10cSrcweir {
858cdf0e10cSrcweir     osl::MutexGuard aGuard( m_aMutex );
859cdf0e10cSrcweir 
860cdf0e10cSrcweir     ENSURE_OR_RETURN_FALSE( mpCanvas.get(),
861cdf0e10cSrcweir                        "SlideView::paintScreen(): Disposed" );
862cdf0e10cSrcweir 
863cdf0e10cSrcweir     return mpCanvas->updateScreen( true );
864cdf0e10cSrcweir }
865cdf0e10cSrcweir 
clear() const866cdf0e10cSrcweir void SlideView::clear() const
867cdf0e10cSrcweir {
868cdf0e10cSrcweir     osl::MutexGuard aGuard( m_aMutex );
869cdf0e10cSrcweir 
870*b06e87e7Smseidel     OSL_ENSURE( mxView.is() && mpCanvas,
871cdf0e10cSrcweir                 "SlideView::clear(): Disposed" );
872cdf0e10cSrcweir     if( !mxView.is() || !mpCanvas )
873cdf0e10cSrcweir         return;
874cdf0e10cSrcweir 
875cdf0e10cSrcweir     // keep layer clip
876cdf0e10cSrcweir     clearRect(getCanvas()->clone(),
877cdf0e10cSrcweir               getLayerBoundsPixel(
878cdf0e10cSrcweir                   basegfx::B2DRange(0,0,
879cdf0e10cSrcweir                                     maUserSize.getX(),
880cdf0e10cSrcweir                                     maUserSize.getY()),
881cdf0e10cSrcweir                   getTransformation()));
882cdf0e10cSrcweir }
883cdf0e10cSrcweir 
clearAll() const884cdf0e10cSrcweir void SlideView::clearAll() const
885cdf0e10cSrcweir {
886cdf0e10cSrcweir     osl::MutexGuard aGuard( m_aMutex );
887cdf0e10cSrcweir 
888*b06e87e7Smseidel     OSL_ENSURE( mxView.is() && mpCanvas,
889cdf0e10cSrcweir                 "SlideView::clear(): Disposed" );
890cdf0e10cSrcweir     if( !mxView.is() || !mpCanvas )
891cdf0e10cSrcweir         return;
892cdf0e10cSrcweir 
893cdf0e10cSrcweir     // clear whole view
894cdf0e10cSrcweir     mxView->clear();
895cdf0e10cSrcweir }
896cdf0e10cSrcweir 
setViewSize(const basegfx::B2DSize & rSize)897cdf0e10cSrcweir void SlideView::setViewSize( const basegfx::B2DSize& rSize )
898cdf0e10cSrcweir {
899cdf0e10cSrcweir     osl::MutexGuard aGuard( m_aMutex );
900cdf0e10cSrcweir 
901cdf0e10cSrcweir     maUserSize = rSize;
902cdf0e10cSrcweir     updateCanvas();
903cdf0e10cSrcweir }
904cdf0e10cSrcweir 
setCursorShape(sal_Int16 nPointerShape)905cdf0e10cSrcweir void SlideView::setCursorShape( sal_Int16 nPointerShape )
906cdf0e10cSrcweir {
907cdf0e10cSrcweir     osl::MutexGuard const guard( m_aMutex );
908cdf0e10cSrcweir 
909cdf0e10cSrcweir     if (mxView.is())
910cdf0e10cSrcweir         mxView->setMouseCursor( nPointerShape );
911cdf0e10cSrcweir }
912cdf0e10cSrcweir 
isOnView(boost::shared_ptr<View> const & rView) const913cdf0e10cSrcweir bool SlideView::isOnView(boost::shared_ptr<View> const& rView) const
914cdf0e10cSrcweir {
915cdf0e10cSrcweir     return rView.get() == this;
916cdf0e10cSrcweir }
917cdf0e10cSrcweir 
getCanvas() const918cdf0e10cSrcweir cppcanvas::CanvasSharedPtr SlideView::getCanvas() const
919cdf0e10cSrcweir {
920cdf0e10cSrcweir     osl::MutexGuard aGuard( m_aMutex );
921cdf0e10cSrcweir 
922*b06e87e7Smseidel     ENSURE_OR_THROW( mpCanvas,
923cdf0e10cSrcweir                       "SlideView::getCanvas(): Disposed" );
924cdf0e10cSrcweir 
925cdf0e10cSrcweir     return mpCanvas;
926cdf0e10cSrcweir }
927cdf0e10cSrcweir 
createSprite(const basegfx::B2DSize & rSpriteSizePixel,double nPriority) const928cdf0e10cSrcweir cppcanvas::CustomSpriteSharedPtr SlideView::createSprite(
929cdf0e10cSrcweir     const basegfx::B2DSize& rSpriteSizePixel,
930*b06e87e7Smseidel     double                  nPriority ) const
931cdf0e10cSrcweir {
932cdf0e10cSrcweir     osl::MutexGuard aGuard( m_aMutex );
933cdf0e10cSrcweir 
934cdf0e10cSrcweir     ENSURE_OR_THROW( mpCanvas, "SlideView::createSprite(): Disposed" );
935cdf0e10cSrcweir 
936cdf0e10cSrcweir     cppcanvas::CustomSpriteSharedPtr pSprite(
937cdf0e10cSrcweir         mpCanvas->createCustomSprite( rSpriteSizePixel ) );
938cdf0e10cSrcweir 
939cdf0e10cSrcweir     maSprites.addSprite( pSprite,
940cdf0e10cSrcweir                          nPriority );
941cdf0e10cSrcweir 
942cdf0e10cSrcweir     return pSprite;
943cdf0e10cSrcweir }
944cdf0e10cSrcweir 
setPriority(const basegfx::B1DRange &)945cdf0e10cSrcweir void SlideView::setPriority( const basegfx::B1DRange& /*rRange*/ )
946cdf0e10cSrcweir {
947cdf0e10cSrcweir     osl::MutexGuard aGuard( m_aMutex );
948cdf0e10cSrcweir 
949cdf0e10cSrcweir     OSL_ENSURE( false,
950cdf0e10cSrcweir                 "SlideView::setPriority() is a NOOP for slide view - "
951cdf0e10cSrcweir                 "content will always be shown in the background" );
952cdf0e10cSrcweir }
953cdf0e10cSrcweir 
getTransformation() const954cdf0e10cSrcweir basegfx::B2DHomMatrix SlideView::getTransformation() const
955cdf0e10cSrcweir {
956cdf0e10cSrcweir     osl::MutexGuard aGuard( m_aMutex );
957cdf0e10cSrcweir 
958cdf0e10cSrcweir     basegfx::B2DHomMatrix aMatrix;
959cdf0e10cSrcweir     aMatrix.scale( 1.0/maUserSize.getX(), 1.0/maUserSize.getY() );
960cdf0e10cSrcweir 
961cdf0e10cSrcweir     return maViewTransform * aMatrix;
962cdf0e10cSrcweir }
963cdf0e10cSrcweir 
getSpriteTransformation() const964cdf0e10cSrcweir basegfx::B2DHomMatrix SlideView::getSpriteTransformation() const
965cdf0e10cSrcweir {
966cdf0e10cSrcweir     return getTransformation();
967cdf0e10cSrcweir }
968cdf0e10cSrcweir 
setClip(const basegfx::B2DPolyPolygon & rClip)969cdf0e10cSrcweir void SlideView::setClip( const basegfx::B2DPolyPolygon& rClip )
970cdf0e10cSrcweir {
971cdf0e10cSrcweir     osl::MutexGuard aGuard( m_aMutex );
972cdf0e10cSrcweir 
973cdf0e10cSrcweir     basegfx::B2DPolyPolygon aNewClip = prepareClip( rClip );
974*b06e87e7Smseidel 
975cdf0e10cSrcweir     if( aNewClip != maClip )
976cdf0e10cSrcweir     {
977*b06e87e7Smseidel         maClip = aNewClip;
978*b06e87e7Smseidel 
979cdf0e10cSrcweir         updateClip();
980cdf0e10cSrcweir     }
981cdf0e10cSrcweir }
982cdf0e10cSrcweir 
resize(const::basegfx::B2DRange &)983cdf0e10cSrcweir bool SlideView::resize( const ::basegfx::B2DRange& /*rArea*/ )
984cdf0e10cSrcweir {
985cdf0e10cSrcweir     osl::MutexGuard aGuard( m_aMutex );
986cdf0e10cSrcweir 
987cdf0e10cSrcweir     OSL_ENSURE( false,
988cdf0e10cSrcweir                 "SlideView::resize(): ignored for the View, can't change size "
989cdf0e10cSrcweir                 "effectively, anyway" );
990cdf0e10cSrcweir 
991cdf0e10cSrcweir     return false;
992cdf0e10cSrcweir }
993cdf0e10cSrcweir 
getUnoView() const994cdf0e10cSrcweir uno::Reference<presentation::XSlideShowView> SlideView::getUnoView() const
995cdf0e10cSrcweir {
996cdf0e10cSrcweir     osl::MutexGuard aGuard( m_aMutex );
997cdf0e10cSrcweir     return mxView;
998cdf0e10cSrcweir }
999cdf0e10cSrcweir 
setIsSoundEnabled(const bool bValue)1000cdf0e10cSrcweir void SlideView::setIsSoundEnabled (const bool bValue)
1001cdf0e10cSrcweir {
1002cdf0e10cSrcweir     mbIsSoundEnabled = bValue;
1003cdf0e10cSrcweir }
1004cdf0e10cSrcweir 
isSoundEnabled(void) const1005cdf0e10cSrcweir bool SlideView::isSoundEnabled (void) const
1006cdf0e10cSrcweir {
1007cdf0e10cSrcweir     return mbIsSoundEnabled;
1008cdf0e10cSrcweir }
1009cdf0e10cSrcweir 
_dispose()1010cdf0e10cSrcweir void SlideView::_dispose()
1011cdf0e10cSrcweir {
1012cdf0e10cSrcweir     dispose();
1013cdf0e10cSrcweir }
1014cdf0e10cSrcweir 
1015cdf0e10cSrcweir // XEventListener
disposing(lang::EventObject const & evt)1016cdf0e10cSrcweir void SlideView::disposing( lang::EventObject const& evt )
1017cdf0e10cSrcweir     throw (uno::RuntimeException)
1018cdf0e10cSrcweir {
1019cdf0e10cSrcweir     (void)evt;
1020cdf0e10cSrcweir 
1021cdf0e10cSrcweir     // no deregistration necessary anymore, XView has left:
1022cdf0e10cSrcweir     osl::MutexGuard const guard( m_aMutex );
1023cdf0e10cSrcweir 
1024*b06e87e7Smseidel     if (mxView.is())
1025cdf0e10cSrcweir     {
1026cdf0e10cSrcweir         OSL_ASSERT( evt.Source == mxView );
1027cdf0e10cSrcweir         mxView.clear();
1028cdf0e10cSrcweir     }
1029cdf0e10cSrcweir 
1030cdf0e10cSrcweir     dispose();
1031cdf0e10cSrcweir }
1032cdf0e10cSrcweir 
1033cdf0e10cSrcweir // XModifyListener
modified(const lang::EventObject &)1034cdf0e10cSrcweir void SlideView::modified( const lang::EventObject& /*aEvent*/ )
1035cdf0e10cSrcweir     throw (uno::RuntimeException)
1036cdf0e10cSrcweir {
1037cdf0e10cSrcweir     osl::MutexGuard const guard( m_aMutex );
1038cdf0e10cSrcweir 
1039cdf0e10cSrcweir     OSL_ENSURE( mxView.is(), "SlideView::modified(): "
1040cdf0e10cSrcweir                 "Disposed, but event received from XSlideShowView?!");
1041cdf0e10cSrcweir 
1042cdf0e10cSrcweir     if( !mxView.is() )
1043cdf0e10cSrcweir         return;
1044*b06e87e7Smseidel 
1045cdf0e10cSrcweir     geometry::AffineMatrix2D aViewTransform(
1046cdf0e10cSrcweir         mxView->getTransformation() );
1047cdf0e10cSrcweir 
1048cdf0e10cSrcweir     if( basegfx::fTools::equalZero(
1049cdf0e10cSrcweir             basegfx::B2DVector(aViewTransform.m00,
1050cdf0e10cSrcweir                                aViewTransform.m10).getLength()) ||
1051cdf0e10cSrcweir         basegfx::fTools::equalZero(
1052cdf0e10cSrcweir             basegfx::B2DVector(aViewTransform.m01,
1053cdf0e10cSrcweir                                aViewTransform.m11).getLength()) )
1054cdf0e10cSrcweir     {
1055*b06e87e7Smseidel         OSL_ENSURE( false,
1056cdf0e10cSrcweir                     "SlideView::modified(): Singular matrix!" );
1057cdf0e10cSrcweir 
1058cdf0e10cSrcweir         canvas::tools::setIdentityAffineMatrix2D(aViewTransform);
1059cdf0e10cSrcweir     }
1060*b06e87e7Smseidel 
1061cdf0e10cSrcweir     // view transformation really changed?
1062cdf0e10cSrcweir     basegfx::B2DHomMatrix aNewTransform;
1063cdf0e10cSrcweir     basegfx::unotools::homMatrixFromAffineMatrix(
1064*b06e87e7Smseidel         aNewTransform,
1065cdf0e10cSrcweir         aViewTransform );
1066cdf0e10cSrcweir 
1067cdf0e10cSrcweir     if( aNewTransform == maViewTransform )
1068cdf0e10cSrcweir         return; // No change, nothing to do
1069*b06e87e7Smseidel 
1070cdf0e10cSrcweir     maViewTransform = aNewTransform;
1071cdf0e10cSrcweir 
1072cdf0e10cSrcweir     updateCanvas();
1073*b06e87e7Smseidel 
1074cdf0e10cSrcweir     // notify view change. Don't call EventMultiplexer directly, this
1075cdf0e10cSrcweir     // might not be the main thread!
1076cdf0e10cSrcweir     mrEventQueue.addEvent(
1077cdf0e10cSrcweir         makeEvent( boost::bind( (bool (EventMultiplexer::*)(
1078cdf0e10cSrcweir                                      const uno::Reference<presentation::XSlideShowView>&))
1079cdf0e10cSrcweir                                 &EventMultiplexer::notifyViewChanged,
1080cdf0e10cSrcweir                                 boost::ref(mrEventMultiplexer), mxView ),
1081cdf0e10cSrcweir                    "EventMultiplexer::notifyViewChanged"));
1082cdf0e10cSrcweir }
1083cdf0e10cSrcweir 
1084cdf0e10cSrcweir // XPaintListener
windowPaint(const awt::PaintEvent &)1085cdf0e10cSrcweir void SlideView::windowPaint( const awt::PaintEvent& /*e*/ )
1086cdf0e10cSrcweir     throw (uno::RuntimeException)
1087cdf0e10cSrcweir {
1088cdf0e10cSrcweir     osl::MutexGuard aGuard( m_aMutex );
1089cdf0e10cSrcweir 
1090cdf0e10cSrcweir     OSL_ENSURE( mxView.is() && mpCanvas, "Disposed, but event received?!" );
1091*b06e87e7Smseidel 
1092cdf0e10cSrcweir     // notify view clobbering. Don't call EventMultiplexer directly,
1093cdf0e10cSrcweir     // this might not be the main thread!
1094cdf0e10cSrcweir     mrEventQueue.addEvent(
1095cdf0e10cSrcweir         makeEvent( boost::bind( &EventMultiplexer::notifyViewClobbered,
1096cdf0e10cSrcweir                                 boost::ref(mrEventMultiplexer), mxView ),
1097cdf0e10cSrcweir                    "EventMultiplexer::notifyViewClobbered") );
1098cdf0e10cSrcweir }
1099cdf0e10cSrcweir 
updateCanvas()1100cdf0e10cSrcweir void SlideView::updateCanvas()
1101cdf0e10cSrcweir {
1102*b06e87e7Smseidel     OSL_ENSURE( mpCanvas,
1103cdf0e10cSrcweir                 "SlideView::updateCanvasTransform(): Disposed" );
1104cdf0e10cSrcweir 
1105cdf0e10cSrcweir     if( !mpCanvas || !mxView.is())
1106cdf0e10cSrcweir         return;
1107*b06e87e7Smseidel 
1108cdf0e10cSrcweir     mpCanvas->clear(); // this is unnecessary, strictly speaking. but
1109cdf0e10cSrcweir                        // it makes the SlideView behave exactly like a
1110cdf0e10cSrcweir                        // sprite-based SlideViewLayer, because those
1111cdf0e10cSrcweir                        // are created from scratch after a resize
1112cdf0e10cSrcweir     clearAll();
1113cdf0e10cSrcweir     mpCanvas->setTransformation( getTransformation() );
1114*b06e87e7Smseidel     mpCanvas->setClip(
1115cdf0e10cSrcweir         createClipPolygon( maClip,
1116cdf0e10cSrcweir                            mpCanvas,
1117cdf0e10cSrcweir                            maUserSize ));
1118cdf0e10cSrcweir 
1119cdf0e10cSrcweir     // forward update to viewlayers
1120cdf0e10cSrcweir     pruneLayers( true );
1121cdf0e10cSrcweir }
1122cdf0e10cSrcweir 
updateClip()1123cdf0e10cSrcweir void SlideView::updateClip()
1124cdf0e10cSrcweir {
1125*b06e87e7Smseidel     OSL_ENSURE( mpCanvas,
1126cdf0e10cSrcweir                 "SlideView::updateClip(): Disposed" );
1127cdf0e10cSrcweir 
1128cdf0e10cSrcweir     if( !mpCanvas )
1129cdf0e10cSrcweir         return;
1130*b06e87e7Smseidel 
1131*b06e87e7Smseidel     mpCanvas->setClip(
1132cdf0e10cSrcweir         createClipPolygon( maClip,
1133cdf0e10cSrcweir                            mpCanvas,
1134cdf0e10cSrcweir                            maUserSize ));
1135cdf0e10cSrcweir 
1136cdf0e10cSrcweir     pruneLayers( false );
1137cdf0e10cSrcweir }
1138cdf0e10cSrcweir 
pruneLayers(bool bWithViewLayerUpdate) const1139cdf0e10cSrcweir void SlideView::pruneLayers( bool bWithViewLayerUpdate ) const
1140cdf0e10cSrcweir {
1141cdf0e10cSrcweir     ViewLayerVector aValidLayers;
1142cdf0e10cSrcweir 
1143*b06e87e7Smseidel     const basegfx::B2DHomMatrix& rCurrTransform(
1144cdf0e10cSrcweir         getTransformation() );
1145cdf0e10cSrcweir 
1146cdf0e10cSrcweir     // check all layers for validity, and retain only the live ones
1147cdf0e10cSrcweir     ViewLayerVector::const_iterator       aCurr( maViewLayers.begin() );
1148cdf0e10cSrcweir     const ViewLayerVector::const_iterator aEnd( maViewLayers.end() );
1149cdf0e10cSrcweir     while( aCurr != aEnd )
1150cdf0e10cSrcweir     {
1151cdf0e10cSrcweir         boost::shared_ptr< SlideViewLayer > pCurrLayer( aCurr->lock() );
1152*b06e87e7Smseidel 
1153cdf0e10cSrcweir         if( pCurrLayer )
1154cdf0e10cSrcweir         {
1155cdf0e10cSrcweir             aValidLayers.push_back( pCurrLayer );
1156*b06e87e7Smseidel 
1157cdf0e10cSrcweir             if( bWithViewLayerUpdate )
1158cdf0e10cSrcweir                 pCurrLayer->updateView( rCurrTransform,
1159cdf0e10cSrcweir                                         maUserSize );
1160cdf0e10cSrcweir         }
1161cdf0e10cSrcweir 
1162cdf0e10cSrcweir         ++aCurr;
1163cdf0e10cSrcweir     }
1164cdf0e10cSrcweir 
1165cdf0e10cSrcweir     // replace layer list with pruned one
1166cdf0e10cSrcweir     maViewLayers.swap( aValidLayers );
1167cdf0e10cSrcweir }
1168cdf0e10cSrcweir 
1169cdf0e10cSrcweir } // anonymous namespace
1170cdf0e10cSrcweir 
createSlideView(uno::Reference<presentation::XSlideShowView> const & xView,EventQueue & rEventQueue,EventMultiplexer & rEventMultiplexer)1171cdf0e10cSrcweir UnoViewSharedPtr createSlideView( uno::Reference< presentation::XSlideShowView> const& xView,
1172cdf0e10cSrcweir                                   EventQueue&                                          rEventQueue,
1173cdf0e10cSrcweir                                   EventMultiplexer&                                    rEventMultiplexer )
1174cdf0e10cSrcweir {
1175cdf0e10cSrcweir     boost::shared_ptr<SlideView> const that(
1176cdf0e10cSrcweir         comphelper::make_shared_from_UNO(
1177*b06e87e7Smseidel             new SlideView(xView,
1178cdf0e10cSrcweir                           rEventQueue,
1179cdf0e10cSrcweir                           rEventMultiplexer)));
1180cdf0e10cSrcweir 
1181cdf0e10cSrcweir     // register listeners with XSlideShowView
1182cdf0e10cSrcweir     xView->addTransformationChangedListener( that.get() );
1183cdf0e10cSrcweir     xView->addPaintListener( that.get() );
1184*b06e87e7Smseidel 
1185cdf0e10cSrcweir     // set new transformation
1186cdf0e10cSrcweir     that->updateCanvas();
1187*b06e87e7Smseidel 
1188cdf0e10cSrcweir     return that;
1189cdf0e10cSrcweir }
1190cdf0e10cSrcweir 
1191cdf0e10cSrcweir } // namespace internal
1192cdf0e10cSrcweir } // namespace slideshow
1193cdf0e10cSrcweir 
1194