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