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