summaryrefslogtreecommitdiff
path: root/slideshow/source/engine/slide/layer.hxx
blob: 3001bc3b8e6d580a37315c082dd01371f40e8318 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef INCLUDED_SLIDESHOW_LAYER_HXX
#define INCLUDED_SLIDESHOW_LAYER_HXX

#include <basegfx/range/b2dmultirange.hxx>
#include <cppcanvas/spritecanvas.hxx>

#include "view.hxx"
#include "animatableshape.hxx"

#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/noncopyable.hpp>
#include <boost/enable_shared_from_this.hpp>

#include <vector>


namespace slideshow
{
    namespace internal
    {
        class LayerEndUpdate;

        /* Definition of Layer class */

        /** This class represents one layer of output on a Slide.

            Layers group shapes for a certain depth region of a slide.

            Since slides have a notion of depth, i.e. shapes on it
            have a certain order in which they lie upon each other,
            this layering must be modeled. A prime example for this
            necessity are animations of shapes lying behind other
            shapes. Then, everything behind the animated shape will be
            in a background layer, the shape itself will be in an
            animation layer, and everything before it will be in a
            foreground layer (these layers are most preferrably
            modeled as XSprite objects internally).

            @attention All methods of this class are only supposed to
            be called from the LayerManager. Normally, it shouldn't be
            possible to get hold of an instance of this class at all.
         */
        class Layer : public boost::enable_shared_from_this<Layer>,
                      private boost::noncopyable
        {
        public:
            typedef boost::shared_ptr<LayerEndUpdate> EndUpdater;

            /** Create background layer

                This method will create a layer without a ViewLayer,
                i.e. one that displays directly on the background.

                @param rMaxLayerBounds
                Maximal bounds of this layer, in user
                coordinates. This layer will never be larger or extend
                outside these bounds.
             */
            static ::boost::shared_ptr< Layer > createBackgroundLayer( const basegfx::B2DRange& rMaxLayerBounds );

            /** Create non-background layer

                This method will create a layer in front of the
                background, to contain shapes that should appear in
                front of animated objects.

                @param rMaxLayerBounds
                Maximal bounds of this layer, in user
                coordinates. This layer will never be larger or extend
                outside these bounds.
             */
            static ::boost::shared_ptr< Layer > createLayer( const basegfx::B2DRange& rMaxLayerBounds );


            /////////////////////////////////////////////////////////////////////


            /** Predicate, whether this layer is the special
                background layer

                This method is mostly useful for checking invariants.
             */
            bool isBackgroundLayer() const { return mbBackgroundLayer; }

            /** Add a view to this layer.

                If the view is already added, this method does not add
                it a second time, just returning the existing ViewLayer.

                @param rNewView
                New view to add to this layer.

                @return the newly generated ViewLayer for this View
             */
            ViewLayerSharedPtr addView( const ViewSharedPtr& rNewView );

            /** Remove a view

                This method removes the view from this Layer and all
                shapes included herein.

                @return the ViewLayer of the removed Layer, if
                any. Otherwise, NULL is returned.
             */
            ViewLayerSharedPtr removeView( const ViewSharedPtr& rView );

            /** Notify that given ViewLayer has changed

                @param rChangedView
                This view's layer will get resized. Afterwards, a
                complete repaint might be necessary.
             */
            void viewChanged( const ViewSharedPtr& rChangedView );

            /** Notify that all ViewLayer have changed

                This resizes all view layers. Afterwards, a complete
                repaint might be necessary.
             */
            void viewsChanged();

            /** Init shape with this layer's views

                @param rShape
                The shape, that will subsequently display on this
                layer's views
             */
            void setShapeViews( ShapeSharedPtr const& rShape ) const;


            /////////////////////////////////////////////////////////////////////


            /** Change layer priority range.

                The layer priority affects the position of the layer
                in the z direction (i.e. before/behind which other
                layers this one appears). The higher the prio, the
                further on top of the layer stack this one appears.

                @param rPrioRange
                The priority range of differing layers must not
                intersect
             */
            void setPriority( const ::basegfx::B1DRange& rPrioRange );

            /** Add an area that needs update

                @param rUpdateRange
                Area on this layer that needs update
             */
            void addUpdateRange( ::basegfx::B2DRange const& rUpdateRange );

            /** Whether any update ranges have been added

                @return true, if any non-empty addUpdateRange() calls
                have been made since the last render()/update() call.
             */
            bool isUpdatePending() const { return !maUpdateAreas.isEmpty(); }

            /** Update layer bound rect from shape bounds
             */
            void updateBounds( ShapeSharedPtr const& rShape );

            /** Commit collected layer bounds to ViewLayer

                Call this method when you're done adding new shapes to
                the layer.

                @return true, if layer needed a resize (which
                invalidates its content - you have to repaint all
                contained shapes!)
             */
            bool commitBounds();

            /** Clear all registered update ranges

                This method clears all update ranges that are
                registered at this layer.
             */
            void clearUpdateRanges();

            /** Clear whole layer content

                This method clears the whole layer content. As a
                byproduct, all update ranges are cleared as well. It
                makes no sense to maintain them any further, since
                they only serve for partial updates.
             */
            void clearContent();

            /** Init layer update.

                This method initializes a full layer update of the
                update area. When the last copy of the returned
                EndUpdater is destroyed, the Layer leaves update mode
                again.

                @return a update end RAII object.
            */
            EndUpdater beginUpdate();

            /** Finish layer update

                Resets clipping and transformation to normal values
             */
            void endUpdate();

            /** Check whether given shape is inside current update area.

                @return true, if the given shape is at least partially
                inside the current update area.
            */
            bool isInsideUpdateArea( ShapeSharedPtr const& rShape ) const;

        private:
            enum Dummy{ BackgroundLayer };

            /** Create background layer

                This constructor will create a layer without a
                ViewLayer, i.e. one that displays directly on the
                background.

                @param rMaxLayerBounds
                Maximal bounds of this layer, in user
                coordinates. This layer will never be larger or extend
                outside these bounds.

                @param eFlag
                Dummy parameter, to disambiguate from normal layer
                constructor
             */
            Layer( const basegfx::B2DRange& rMaxLayerBounds,
                   Dummy                    eFlag );

            /** Create non-background layer

                This constructor will create a layer in front of the
                background, to contain shapes that should appear in
                front of animated objects.

                @param rMaxLayerBounds
                Maximal bounds of this layer, in user
                coordinates. This layer will never be larger or extend
                outside these bounds.
             */
            explicit Layer( const basegfx::B2DRange& rMaxLayerBounds );

            struct ViewEntry
            {
                ViewEntry( const ViewSharedPtr&      rView,
                           const ViewLayerSharedPtr& rViewLayer ) :
                    mpView( rView ),
                    mpViewLayer( rViewLayer )
                {}

                ViewSharedPtr      mpView;
                ViewLayerSharedPtr mpViewLayer;

                // for generic algo access (which needs actual functions)
                const ViewSharedPtr&      getView() const { return mpView; }
                const ViewLayerSharedPtr& getViewLayer() const { return mpViewLayer; }
            };

            typedef ::std::vector< ViewEntry > ViewEntryVector;

            ViewEntryVector            maViewEntries;
            basegfx::B2DMultiRange     maUpdateAreas;
            basegfx::B2DRange          maBounds;
            basegfx::B2DRange          maNewBounds;
            const basegfx::B2DRange    maMaxBounds;       // maBounds is clipped against this
            bool                       mbBoundsDirty;     // true, if view layers need resize
            bool                       mbBackgroundLayer; // true, if this
                                                          // layer is the
                                                          // special
                                                          // background layer
            bool                       mbClipSet; // true, if beginUpdate set a clip
        };

        typedef ::boost::shared_ptr< Layer >    LayerSharedPtr;
        typedef ::boost::weak_ptr< Layer >      LayerWeakPtr;
        typedef ::std::vector< LayerSharedPtr > LayerVector;

    }
}

#endif /* INCLUDED_SLIDESHOW_LAYER_HXX */