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