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