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 modelled. 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 preferably 61 modelled 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