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_LAYER_HXX
29 #define INCLUDED_SLIDESHOW_LAYER_HXX
30 
31 #include <basegfx/range/b2dpolyrange.hxx>
32 #include <cppcanvas/spritecanvas.hxx>
33 
34 #include "view.hxx"
35 #include "animatableshape.hxx"
36 
37 #include <boost/shared_ptr.hpp>
38 #include <boost/weak_ptr.hpp>
39 #include <boost/noncopyable.hpp>
40 #include <boost/enable_shared_from_this.hpp>
41 
42 #include <vector>
43 
44 
45 namespace slideshow
46 {
47     namespace internal
48     {
49         class LayerEndUpdate;
50 
51 		/* Definition of Layer class */
52 
53         /** This class represents one layer of output on a Slide.
54 
55         	Layers group shapes for a certain depth region of a slide.
56 
57         	Since slides have a notion of depth, i.e. shapes on it
58         	have a certain order in which they lie upon each other,
59         	this layering must be modeled. A prime example for this
60         	necessity are animations of shapes lying behind other
61         	shapes. Then, everything behind the animated shape will be
62         	in a background layer, the shape itself will be in an
63         	animation layer, and everything before it will be in a
64         	foreground layer (these layers are most preferrably
65         	modeled as XSprite objects internally).
66 
67             @attention All methods of this class are only supposed to
68             be called from the LayerManager. Normally, it shouldn't be
69             possible to get hold of an instance of this class at all.
70          */
71         class Layer : public boost::enable_shared_from_this<Layer>,
72                       private boost::noncopyable
73         {
74         public:
75             typedef boost::shared_ptr<LayerEndUpdate> EndUpdater;
76 
77             /** Create background layer
78 
79                 This method will create a layer without a ViewLayer,
80                 i.e. one that displays directly on the background.
81 
82                 @param rMaxLayerBounds
83                 Maximal bounds of this layer, in user
84                 coordinates. This layer will never be larger or extend
85                 outside these bounds.
86              */
87             static ::boost::shared_ptr< Layer > createBackgroundLayer( const basegfx::B2DRange& rMaxLayerBounds );
88 
89             /** Create non-background layer
90 
91                 This method will create a layer in front of the
92                 background, to contain shapes that should appear in
93                 front of animated objects.
94 
95                 @param rMaxLayerBounds
96                 Maximal bounds of this layer, in user
97                 coordinates. This layer will never be larger or extend
98                 outside these bounds.
99              */
100             static ::boost::shared_ptr< Layer > createLayer( const basegfx::B2DRange& rMaxLayerBounds );
101 
102 
103             /////////////////////////////////////////////////////////////////////
104 
105 
106             /** Predicate, whether this layer is the special
107                 background layer
108 
109                 This method is mostly useful for checking invariants.
110              */
111             bool isBackgroundLayer() const { return mbBackgroundLayer; }
112 
113             /** Add a view to this layer.
114 
115                 If the view is already added, this method does not add
116                 it a second time, just returning the existing ViewLayer.
117 
118                 @param rNewView
119                 New view to add to this layer.
120 
121                 @return the newly generated ViewLayer for this View
122              */
123             ViewLayerSharedPtr addView( const ViewSharedPtr& rNewView );
124 
125             /** Remove a view
126 
127             	This method removes the view from this Layer and all
128             	shapes included herein.
129 
130                 @return the ViewLayer of the removed Layer, if
131                 any. Otherwise, NULL is returned.
132              */
133             ViewLayerSharedPtr removeView( const ViewSharedPtr& rView );
134 
135             /** Notify that given ViewLayer has changed
136 
137                 @param rChangedView
138                 This view's layer will get resized. Afterwards, a
139                 complete repaint might be necessary.
140              */
141             void viewChanged( const ViewSharedPtr& rChangedView );
142 
143             /** Notify that all ViewLayer have changed
144 
145                 This resizes all view layers. Afterwards, a complete
146                 repaint might be necessary.
147              */
148             void viewsChanged();
149 
150             /** Init shape with this layer's views
151 
152                 @param rShape
153                 The shape, that will subsequently display on this
154                 layer's views
155              */
156             void setShapeViews( ShapeSharedPtr const& rShape ) const;
157 
158 
159             /////////////////////////////////////////////////////////////////////
160 
161 
162             /** Change layer priority range.
163 
164                 The layer priority affects the position of the layer
165                 in the z direction (i.e. before/behind which other
166                 layers this one appears). The higher the prio, the
167                 further on top of the layer stack this one appears.
168 
169                 @param rPrioRange
170                 The priority range of differing layers must not
171                 intersect
172              */
173             void setPriority( const ::basegfx::B1DRange& rPrioRange );
174 
175             /** Add an area that needs update
176 
177                 @param rUpdateRange
178                 Area on this layer that needs update
179              */
180             void addUpdateRange( ::basegfx::B2DRange const& rUpdateRange );
181 
182             /** Whether any update ranges have been added
183 
184                 @return true, if any non-empty addUpdateRange() calls
185                 have been made since the last render()/update() call.
186              */
187             bool isUpdatePending() const { return maUpdateAreas.count()!=0; }
188 
189             /** Update layer bound rect from shape bounds
190              */
191             void updateBounds( ShapeSharedPtr const& rShape );
192 
193             /** Commit collected layer bounds to ViewLayer
194 
195                 Call this method when you're done adding new shapes to
196                 the layer.
197 
198                 @return true, if layer needed a resize (which
199                 invalidates its content - you have to repaint all
200                 contained shapes!)
201              */
202             bool commitBounds();
203 
204             /** Clear all registered update ranges
205 
206                 This method clears all update ranges that are
207                 registered at this layer.
208              */
209             void clearUpdateRanges();
210 
211             /** Clear whole layer content
212 
213                 This method clears the whole layer content. As a
214                 byproduct, all update ranges are cleared as well. It
215                 makes no sense to maintain them any further, since
216                 they only serve for partial updates.
217              */
218             void clearContent();
219 
220             /** Init layer update.
221 
222 				This method initializes a full layer update of the
223 				update area. When the last copy of the returned
224 				EndUpdater is destroyed, the Layer leaves update mode
225 				again.
226 
227 	            @return a update end RAII object.
228             */
229             EndUpdater beginUpdate();
230 
231             /** Finish layer update
232 
233                 Resets clipping and transformation to normal values
234              */
235             void endUpdate();
236 
237             /** Check whether given shape is inside current update area.
238 
239 				@return true, if the given shape is at least partially
240 				inside the current update area.
241             */
242             bool isInsideUpdateArea( ShapeSharedPtr const& rShape ) const;
243 
244         private:
245             enum Dummy{ BackgroundLayer };
246 
247             /** Create background layer
248 
249                 This constructor will create a layer without a
250                 ViewLayer, i.e. one that displays directly on the
251                 background.
252 
253                 @param rMaxLayerBounds
254                 Maximal bounds of this layer, in user
255                 coordinates. This layer will never be larger or extend
256                 outside these bounds.
257 
258                 @param eFlag
259                 Dummy parameter, to disambiguate from normal layer
260                 constructor
261              */
262             Layer( const basegfx::B2DRange& rMaxLayerBounds,
263                    Dummy                    eFlag );
264 
265             /** Create non-background layer
266 
267                 This constructor will create a layer in front of the
268                 background, to contain shapes that should appear in
269                 front of animated objects.
270 
271                 @param rMaxLayerBounds
272                 Maximal bounds of this layer, in user
273                 coordinates. This layer will never be larger or extend
274                 outside these bounds.
275              */
276             explicit Layer( const basegfx::B2DRange& rMaxLayerBounds );
277 
278             struct ViewEntry
279             {
280                 ViewEntry( const ViewSharedPtr&      rView,
281                            const ViewLayerSharedPtr& rViewLayer ) :
282                     mpView( rView ),
283                     mpViewLayer( rViewLayer )
284                 {}
285 
286                 ViewSharedPtr      mpView;
287                 ViewLayerSharedPtr mpViewLayer;
288 
289                 // for generic algo access (which needs actual functions)
290                 const ViewSharedPtr&      getView() const { return mpView; }
291                 const ViewLayerSharedPtr& getViewLayer() const { return mpViewLayer; }
292             };
293 
294             typedef ::std::vector< ViewEntry > ViewEntryVector;
295 
296             ViewEntryVector            maViewEntries;
297             basegfx::B2DPolyRange      maUpdateAreas;
298             basegfx::B2DRange          maBounds;
299             basegfx::B2DRange          maNewBounds;
300             const basegfx::B2DRange    maMaxBounds;       // maBounds is clipped against this
301             bool                       mbBoundsDirty;     // true, if view layers need resize
302             bool                       mbBackgroundLayer; // true, if this
303                                                           // layer is the
304                                                           // special
305                                                           // background layer
306             bool                       mbClipSet; // true, if beginUpdate set a clip
307         };
308 
309         typedef ::boost::shared_ptr< Layer >    LayerSharedPtr;
310         typedef ::boost::weak_ptr< Layer >      LayerWeakPtr;
311         typedef ::std::vector< LayerSharedPtr > LayerVector;
312 
313     }
314 }
315 
316 #endif /* INCLUDED_SLIDESHOW_LAYER_HXX */
317