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