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 28*cdf0e10cSrcweir #ifndef INCLUDED_SLIDESHOW_LAYERMANAGER_HXX 29*cdf0e10cSrcweir #define INCLUDED_SLIDESHOW_LAYERMANAGER_HXX 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #include <boost/shared_ptr.hpp> 32*cdf0e10cSrcweir #include <boost/noncopyable.hpp> 33*cdf0e10cSrcweir 34*cdf0e10cSrcweir #include <cppcanvas/spritecanvas.hxx> 35*cdf0e10cSrcweir 36*cdf0e10cSrcweir #include "unoview.hxx" 37*cdf0e10cSrcweir #include "unoviewcontainer.hxx" 38*cdf0e10cSrcweir #include "attributableshape.hxx" 39*cdf0e10cSrcweir #include "layer.hxx" 40*cdf0e10cSrcweir #include "tools.hxx" 41*cdf0e10cSrcweir 42*cdf0e10cSrcweir #include <vector> 43*cdf0e10cSrcweir #include <map> 44*cdf0e10cSrcweir #include <hash_map> 45*cdf0e10cSrcweir #include <algorithm> 46*cdf0e10cSrcweir #include <functional> 47*cdf0e10cSrcweir 48*cdf0e10cSrcweir namespace basegfx { 49*cdf0e10cSrcweir class B2DRange; 50*cdf0e10cSrcweir } 51*cdf0e10cSrcweir 52*cdf0e10cSrcweir namespace slideshow 53*cdf0e10cSrcweir { 54*cdf0e10cSrcweir namespace internal 55*cdf0e10cSrcweir { 56*cdf0e10cSrcweir /* Definition of Layermanager class */ 57*cdf0e10cSrcweir 58*cdf0e10cSrcweir /** This class manages all of a slide's layers (and shapes) 59*cdf0e10cSrcweir 60*cdf0e10cSrcweir Since layer content changes when animations start or end, 61*cdf0e10cSrcweir the layer manager keeps track of this and also handles 62*cdf0e10cSrcweir starting/stopping of Shape animations. Note that none of 63*cdf0e10cSrcweir the methods actually perform a screen update, this is 64*cdf0e10cSrcweir always delayed until the ActivitiesQueue explicitely 65*cdf0e10cSrcweir performs it. 66*cdf0e10cSrcweir 67*cdf0e10cSrcweir @see Layer 68*cdf0e10cSrcweir @see Shape 69*cdf0e10cSrcweir */ 70*cdf0e10cSrcweir class LayerManager : private boost::noncopyable 71*cdf0e10cSrcweir { 72*cdf0e10cSrcweir public: 73*cdf0e10cSrcweir /** Create a new layer manager for the given page bounds 74*cdf0e10cSrcweir 75*cdf0e10cSrcweir @param rViews 76*cdf0e10cSrcweir Views currently registered 77*cdf0e10cSrcweir 78*cdf0e10cSrcweir @param rPageBounds 79*cdf0e10cSrcweir Overall page bounds, in user space coordinates 80*cdf0e10cSrcweir 81*cdf0e10cSrcweir @param bDisableAnimationZOrder 82*cdf0e10cSrcweir When true, all sprite animations run in the 83*cdf0e10cSrcweir foreground. That is, no extra layers are created, and 84*cdf0e10cSrcweir the slideshow runs potentially faster. 85*cdf0e10cSrcweir */ 86*cdf0e10cSrcweir LayerManager( const UnoViewContainer& rViews, 87*cdf0e10cSrcweir const ::basegfx::B2DRange& rPageBounds, 88*cdf0e10cSrcweir bool bDisableAnimationZOrder ); 89*cdf0e10cSrcweir 90*cdf0e10cSrcweir /** Activate the LayerManager 91*cdf0e10cSrcweir 92*cdf0e10cSrcweir This method activates the LayerManager. Prior to 93*cdf0e10cSrcweir activation, this instance will be passive, i.e. won't 94*cdf0e10cSrcweir render anything to any view. 95*cdf0e10cSrcweir 96*cdf0e10cSrcweir @param bSlideBackgoundPainted 97*cdf0e10cSrcweir When true, the initial slide content on the background 98*cdf0e10cSrcweir layer is already rendered (e.g. from a previous slide 99*cdf0e10cSrcweir transition). When false, LayerManager also renders 100*cdf0e10cSrcweir initial content of background layer on next update() 101*cdf0e10cSrcweir call. 102*cdf0e10cSrcweir */ 103*cdf0e10cSrcweir void activate( bool bSlideBackgoundPainted ); 104*cdf0e10cSrcweir 105*cdf0e10cSrcweir /** Deactivate the LayerManager 106*cdf0e10cSrcweir 107*cdf0e10cSrcweir This method deactivates the LayerManager. After 108*cdf0e10cSrcweir deactivation, this instance will be passive, 109*cdf0e10cSrcweir i.e. don't render anything to any view. Furthermore, 110*cdf0e10cSrcweir if there's currently more than one Layer active, this 111*cdf0e10cSrcweir method also removes all but one. 112*cdf0e10cSrcweir */ 113*cdf0e10cSrcweir void deactivate(); 114*cdf0e10cSrcweir 115*cdf0e10cSrcweir // From ViewEventHandler, forwarded by SlideImpl 116*cdf0e10cSrcweir /// Notify new view added to UnoViewContainer 117*cdf0e10cSrcweir void viewAdded( const UnoViewSharedPtr& rView ); 118*cdf0e10cSrcweir /// Notify view removed from UnoViewContainer 119*cdf0e10cSrcweir void viewRemoved( const UnoViewSharedPtr& rView ); 120*cdf0e10cSrcweir void viewChanged( const UnoViewSharedPtr& rView ); 121*cdf0e10cSrcweir void viewsChanged(); 122*cdf0e10cSrcweir 123*cdf0e10cSrcweir /** Add the shape to this object 124*cdf0e10cSrcweir 125*cdf0e10cSrcweir This method adds a shape to the page. 126*cdf0e10cSrcweir */ 127*cdf0e10cSrcweir void addShape( const ShapeSharedPtr& rShape ); 128*cdf0e10cSrcweir 129*cdf0e10cSrcweir /** Remove shape from this object 130*cdf0e10cSrcweir 131*cdf0e10cSrcweir This method removes a shape from the shape. 132*cdf0e10cSrcweir */ 133*cdf0e10cSrcweir bool removeShape( const ShapeSharedPtr& rShape ); 134*cdf0e10cSrcweir 135*cdf0e10cSrcweir /** Lookup a Shape from an XShape model object 136*cdf0e10cSrcweir 137*cdf0e10cSrcweir This method looks up the internal shape map for one 138*cdf0e10cSrcweir representing the given XShape. 139*cdf0e10cSrcweir 140*cdf0e10cSrcweir @param xShape 141*cdf0e10cSrcweir The XShape object, for which the representing Shape 142*cdf0e10cSrcweir should be looked up. 143*cdf0e10cSrcweir */ 144*cdf0e10cSrcweir ShapeSharedPtr lookupShape( const ::com::sun::star::uno::Reference< 145*cdf0e10cSrcweir ::com::sun::star::drawing::XShape >& xShape ) const; 146*cdf0e10cSrcweir 147*cdf0e10cSrcweir /** Query a subset of the given original shape 148*cdf0e10cSrcweir 149*cdf0e10cSrcweir This method queries a new (but not necessarily unique) 150*cdf0e10cSrcweir shape, which displays only the given subset of the 151*cdf0e10cSrcweir original one. 152*cdf0e10cSrcweir */ 153*cdf0e10cSrcweir AttributableShapeSharedPtr getSubsetShape( const AttributableShapeSharedPtr& rOrigShape, 154*cdf0e10cSrcweir const DocTreeNode& rTreeNode ); 155*cdf0e10cSrcweir 156*cdf0e10cSrcweir /** Revoke a previously queried subset shape. 157*cdf0e10cSrcweir 158*cdf0e10cSrcweir With this method, a previously requested subset shape 159*cdf0e10cSrcweir is revoked again. If the last client revokes a given 160*cdf0e10cSrcweir subset, it will cease to be displayed, and the 161*cdf0e10cSrcweir original shape will again show the subset data. 162*cdf0e10cSrcweir 163*cdf0e10cSrcweir @param rOrigShape 164*cdf0e10cSrcweir The shape the subset was created from 165*cdf0e10cSrcweir 166*cdf0e10cSrcweir @param rSubsetShape 167*cdf0e10cSrcweir The subset created from rOrigShape 168*cdf0e10cSrcweir */ 169*cdf0e10cSrcweir void revokeSubset( const AttributableShapeSharedPtr& rOrigShape, 170*cdf0e10cSrcweir const AttributableShapeSharedPtr& rSubsetShape ); 171*cdf0e10cSrcweir 172*cdf0e10cSrcweir /** Notify the LayerManager that the given Shape starts an 173*cdf0e10cSrcweir animation now. 174*cdf0e10cSrcweir 175*cdf0e10cSrcweir This method enters animation mode for the Shape on all 176*cdf0e10cSrcweir registered views. 177*cdf0e10cSrcweir */ 178*cdf0e10cSrcweir void enterAnimationMode( const AnimatableShapeSharedPtr& rShape ); 179*cdf0e10cSrcweir 180*cdf0e10cSrcweir /** Notify the LayerManager that the given Shape is no 181*cdf0e10cSrcweir longer animated. 182*cdf0e10cSrcweir 183*cdf0e10cSrcweir This methods ends animation mode for the given Shape 184*cdf0e10cSrcweir on all registered views. 185*cdf0e10cSrcweir */ 186*cdf0e10cSrcweir void leaveAnimationMode( const AnimatableShapeSharedPtr& rShape ); 187*cdf0e10cSrcweir 188*cdf0e10cSrcweir /** Notify that a shape needs an update 189*cdf0e10cSrcweir 190*cdf0e10cSrcweir This method notifies the layer manager that a shape 191*cdf0e10cSrcweir update is necessary. This is useful if, during 192*cdf0e10cSrcweir animation playback, changes occur to shapes which make 193*cdf0e10cSrcweir an update necessary on an update() call. Otherwise, 194*cdf0e10cSrcweir update() will not render anything, which is not 195*cdf0e10cSrcweir triggered by calling one of the other LayerManager 196*cdf0e10cSrcweir methods. 197*cdf0e10cSrcweir 198*cdf0e10cSrcweir @param rShape 199*cdf0e10cSrcweir Shape which needs an update 200*cdf0e10cSrcweir */ 201*cdf0e10cSrcweir void notifyShapeUpdate( const ShapeSharedPtr& rShape); 202*cdf0e10cSrcweir 203*cdf0e10cSrcweir /** Check whether any update operations are pending. 204*cdf0e10cSrcweir 205*cdf0e10cSrcweir @return true, if this LayerManager has any updates 206*cdf0e10cSrcweir pending, i.e. needs to repaint something for the next 207*cdf0e10cSrcweir frame. 208*cdf0e10cSrcweir */ 209*cdf0e10cSrcweir bool isUpdatePending() const; 210*cdf0e10cSrcweir 211*cdf0e10cSrcweir /** Update the content 212*cdf0e10cSrcweir 213*cdf0e10cSrcweir This method updates the content on all layers on all 214*cdf0e10cSrcweir registered views. It does not issues a 215*cdf0e10cSrcweir View::updateScreen() call on registered views. Please 216*cdf0e10cSrcweir note that this method only takes into account changes 217*cdf0e10cSrcweir to shapes induced directly by calling methods of the 218*cdf0e10cSrcweir LayerManager. If a shape needs an update, because of 219*cdf0e10cSrcweir some external event unknown to the LayerManager (most 220*cdf0e10cSrcweir notably running animations), you have to notify the 221*cdf0e10cSrcweir LayerManager via notifyShapeUpdate(). 222*cdf0e10cSrcweir 223*cdf0e10cSrcweir @see LayerManager::updateScreen() 224*cdf0e10cSrcweir 225*cdf0e10cSrcweir @return whether the update finished successfully. 226*cdf0e10cSrcweir */ 227*cdf0e10cSrcweir bool update(); 228*cdf0e10cSrcweir 229*cdf0e10cSrcweir /** Render the content to given canvas 230*cdf0e10cSrcweir 231*cdf0e10cSrcweir This is a one-shot operation, which simply draws all 232*cdf0e10cSrcweir shapes onto the given canvas, without any caching or 233*cdf0e10cSrcweir other fuzz. Don't use that for repeated output onto 234*cdf0e10cSrcweir the same canvas, the View concept is more optimal 235*cdf0e10cSrcweir then. 236*cdf0e10cSrcweir 237*cdf0e10cSrcweir @param rTargetCanvas 238*cdf0e10cSrcweir Target canvas to output onto. 239*cdf0e10cSrcweir */ 240*cdf0e10cSrcweir bool renderTo( const ::cppcanvas::CanvasSharedPtr& rTargetCanvas ) const; 241*cdf0e10cSrcweir 242*cdf0e10cSrcweir private: 243*cdf0e10cSrcweir /** A hash map which maps the XShape to the corresponding Shape object. 244*cdf0e10cSrcweir 245*cdf0e10cSrcweir Provides quicker lookup than ShapeSet for simple mappings 246*cdf0e10cSrcweir */ 247*cdf0e10cSrcweir typedef ::std::hash_map< 248*cdf0e10cSrcweir ::com::sun::star::uno::Reference< 249*cdf0e10cSrcweir ::com::sun::star::drawing::XShape >, 250*cdf0e10cSrcweir ShapeSharedPtr, 251*cdf0e10cSrcweir hash< ::com::sun::star::uno::Reference< 252*cdf0e10cSrcweir ::com::sun::star::drawing::XShape > > > XShapeHash; 253*cdf0e10cSrcweir 254*cdf0e10cSrcweir class ShapeComparator 255*cdf0e10cSrcweir { 256*cdf0e10cSrcweir public: 257*cdf0e10cSrcweir bool operator() (const ShapeSharedPtr& rpS1, const ShapeSharedPtr& rpS2 ) const 258*cdf0e10cSrcweir { 259*cdf0e10cSrcweir return Shape::lessThanShape::compare(rpS1.get(), rpS2.get()); 260*cdf0e10cSrcweir } 261*cdf0e10cSrcweir }; 262*cdf0e10cSrcweir /** Set of all shapes 263*cdf0e10cSrcweir */ 264*cdf0e10cSrcweir private: 265*cdf0e10cSrcweir typedef ::std::map< ShapeSharedPtr, LayerWeakPtr, ShapeComparator > LayerShapeMap; 266*cdf0e10cSrcweir typedef ::std::set< ShapeSharedPtr > ShapeUpdateSet; 267*cdf0e10cSrcweir 268*cdf0e10cSrcweir 269*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////// 270*cdf0e10cSrcweir 271*cdf0e10cSrcweir 272*cdf0e10cSrcweir /// Adds shape area to containing layer's damage area 273*cdf0e10cSrcweir void addUpdateArea( ShapeSharedPtr const& rShape ); 274*cdf0e10cSrcweir 275*cdf0e10cSrcweir LayerSharedPtr createForegroundLayer() const; 276*cdf0e10cSrcweir 277*cdf0e10cSrcweir /** Push changes from updateShapeLayerAssociations() to current layer 278*cdf0e10cSrcweir 279*cdf0e10cSrcweir Factored-out method that resizes layer, if necessary, 280*cdf0e10cSrcweir assigns correct layer priority, and repaints contained shapes. 281*cdf0e10cSrcweir 282*cdf0e10cSrcweir @param nCurrLayerIndex 283*cdf0e10cSrcweir Index of current layer in maLayers 284*cdf0e10cSrcweir 285*cdf0e10cSrcweir @param aFirstLayerShape 286*cdf0e10cSrcweir Valid iterator out of maAllShapes, denoting the first 287*cdf0e10cSrcweir shape from nCurrLayerIndex 288*cdf0e10cSrcweir 289*cdf0e10cSrcweir @param aEndLayerShapes 290*cdf0e10cSrcweir Valid iterator or end iterator out of maAllShapes, 291*cdf0e10cSrcweir denoting one-behind-the-last shape of nCurrLayerIndex 292*cdf0e10cSrcweir */ 293*cdf0e10cSrcweir void commitLayerChanges( std::size_t nCurrLayerIndex, 294*cdf0e10cSrcweir LayerShapeMap::const_iterator aFirstLayerShape, 295*cdf0e10cSrcweir LayerShapeMap::const_iterator aEndLayerShapes ); 296*cdf0e10cSrcweir 297*cdf0e10cSrcweir /** Init Shape layers with background layer. 298*cdf0e10cSrcweir */ 299*cdf0e10cSrcweir void putShape2BackgroundLayer( LayerShapeMap::value_type& rShapeEntry ); 300*cdf0e10cSrcweir 301*cdf0e10cSrcweir /** Commits any pending layer reorg, due to shapes either 302*cdf0e10cSrcweir entering or leaving animation mode 303*cdf0e10cSrcweir 304*cdf0e10cSrcweir @param bBackgroundLayerPainted 305*cdf0e10cSrcweir When true, LayerManager does not render anything on 306*cdf0e10cSrcweir the background layer. Use this, if background has been 307*cdf0e10cSrcweir updated by other means (e.g. slide transition) 308*cdf0e10cSrcweir */ 309*cdf0e10cSrcweir void updateShapeLayers( bool bBackgroundLayerPainted ); 310*cdf0e10cSrcweir 311*cdf0e10cSrcweir /** Common stuff when adding a shape 312*cdf0e10cSrcweir */ 313*cdf0e10cSrcweir void implAddShape( const ShapeSharedPtr& rShape ); 314*cdf0e10cSrcweir 315*cdf0e10cSrcweir /** Common stuff when removing a shape 316*cdf0e10cSrcweir */ 317*cdf0e10cSrcweir void implRemoveShape( const ShapeSharedPtr& rShape ); 318*cdf0e10cSrcweir 319*cdf0e10cSrcweir /** Add or remove views 320*cdf0e10cSrcweir 321*cdf0e10cSrcweir Sharing duplicate code from viewAdded and viewRemoved 322*cdf0e10cSrcweir method. The only point of variation at those places 323*cdf0e10cSrcweir are removal vs. adding. 324*cdf0e10cSrcweir */ 325*cdf0e10cSrcweir template<typename LayerFunc, 326*cdf0e10cSrcweir typename ShapeFunc> void manageViews( LayerFunc layerFunc, 327*cdf0e10cSrcweir ShapeFunc shapeFunc ); 328*cdf0e10cSrcweir 329*cdf0e10cSrcweir bool updateSprites(); 330*cdf0e10cSrcweir 331*cdf0e10cSrcweir /// Registered views 332*cdf0e10cSrcweir const UnoViewContainer& mrViews; 333*cdf0e10cSrcweir 334*cdf0e10cSrcweir /// All layers of this object. Vector owns the layers 335*cdf0e10cSrcweir LayerVector maLayers; 336*cdf0e10cSrcweir 337*cdf0e10cSrcweir /** Contains all shapes with their XShape reference as the key 338*cdf0e10cSrcweir */ 339*cdf0e10cSrcweir XShapeHash maXShapeHash; 340*cdf0e10cSrcweir 341*cdf0e10cSrcweir /** Set of shapes this LayerManager own 342*cdf0e10cSrcweir 343*cdf0e10cSrcweir Contains the same set of shapes as XShapeHash, but is 344*cdf0e10cSrcweir sorted in z order, for painting and layer 345*cdf0e10cSrcweir association. Set entries are enriched with two flags 346*cdf0e10cSrcweir for buffering animation enable/disable changes, and 347*cdf0e10cSrcweir shape update requests. 348*cdf0e10cSrcweir */ 349*cdf0e10cSrcweir LayerShapeMap maAllShapes; 350*cdf0e10cSrcweir 351*cdf0e10cSrcweir /** Set of shapes that have requested an update 352*cdf0e10cSrcweir 353*cdf0e10cSrcweir When a shape is member of this set, its maShapes entry 354*cdf0e10cSrcweir has bNeedsUpdate set to true. We maintain this 355*cdf0e10cSrcweir redundant information for faster update processing. 356*cdf0e10cSrcweir */ 357*cdf0e10cSrcweir ShapeUpdateSet maUpdateShapes; 358*cdf0e10cSrcweir 359*cdf0e10cSrcweir /** Overall slide bounds (in user coordinate 360*cdf0e10cSrcweir system). shapes that exceed this boundary are clipped, 361*cdf0e10cSrcweir thus, layers only need to be of this size. 362*cdf0e10cSrcweir */ 363*cdf0e10cSrcweir const basegfx::B2DRange maPageBounds; 364*cdf0e10cSrcweir 365*cdf0e10cSrcweir /// Number of shape sprites currenly active on this LayerManager 366*cdf0e10cSrcweir sal_Int32 mnActiveSprites; 367*cdf0e10cSrcweir 368*cdf0e10cSrcweir /// sal_True, if shapes might need to move to different layer 369*cdf0e10cSrcweir bool mbLayerAssociationDirty; 370*cdf0e10cSrcweir 371*cdf0e10cSrcweir /// sal_False when deactivated 372*cdf0e10cSrcweir bool mbActive; 373*cdf0e10cSrcweir 374*cdf0e10cSrcweir /** When true, all sprite animations run in the foreground. That 375*cdf0e10cSrcweir is, no extra layers are created, and the slideshow runs 376*cdf0e10cSrcweir potentially faster. 377*cdf0e10cSrcweir */ 378*cdf0e10cSrcweir bool mbDisableAnimationZOrder; 379*cdf0e10cSrcweir }; 380*cdf0e10cSrcweir 381*cdf0e10cSrcweir typedef ::boost::shared_ptr< LayerManager > LayerManagerSharedPtr; 382*cdf0e10cSrcweir } 383*cdf0e10cSrcweir } 384*cdf0e10cSrcweir 385*cdf0e10cSrcweir #endif /* INCLUDED_SLIDESHOW_LAYERMANAGER_HXX */ 386