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 explicitely
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 currenly 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