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