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