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