merge the formfield patch from ooo-build
[ooovba.git] / slideshow / source / engine / slide / layer.cxx
blobf56de722878a4a5df869cfa49792f553502badee
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: layer.cxx,v $
10 * $Revision: 1.4 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_slideshow.hxx"
34 // must be first
35 #include <canvas/debug.hxx>
37 #include <basegfx/range/b2drange.hxx>
38 #include <basegfx/range/b1drange.hxx>
39 #include <basegfx/range/b2dmultirange.hxx>
40 #include <basegfx/matrix/b2dhommatrix.hxx>
41 #include <basegfx/polygon/b2dpolypolygon.hxx>
43 #include "layer.hxx"
45 #include <boost/bind.hpp>
48 using namespace ::com::sun::star;
50 namespace slideshow
52 namespace internal
54 Layer::Layer( const basegfx::B2DRange& rMaxLayerBounds,
55 Dummy ) :
56 maViewEntries(),
57 maBounds(),
58 maNewBounds(),
59 maMaxBounds( rMaxLayerBounds ),
60 mbBoundsDirty(false),
61 mbBackgroundLayer(true),
62 mbClipSet(false)
66 Layer::Layer( const basegfx::B2DRange& rMaxLayerBounds ) :
67 maViewEntries(),
68 maBounds(),
69 maNewBounds(),
70 maMaxBounds( rMaxLayerBounds ),
71 mbBoundsDirty(false),
72 mbBackgroundLayer(false),
73 mbClipSet(false)
77 ViewLayerSharedPtr Layer::addView( const ViewSharedPtr& rNewView )
79 OSL_ASSERT( rNewView );
81 ViewEntryVector::iterator aIter;
82 const ViewEntryVector::iterator aEnd( maViewEntries.end() );
83 if( (aIter=std::find_if( maViewEntries.begin(),
84 aEnd,
85 boost::bind<bool>(
86 std::equal_to< ViewSharedPtr >(),
87 boost::bind( &ViewEntry::getView, _1 ),
88 boost::cref( rNewView )))) != aEnd )
90 // already added - just return existing layer
91 return aIter->mpViewLayer;
95 // not yet added - create new view layer
96 ViewLayerSharedPtr pNewLayer;
97 if( mbBackgroundLayer )
98 pNewLayer = rNewView;
99 else
100 pNewLayer = rNewView->createViewLayer(maBounds);
102 // add to local list
103 maViewEntries.push_back(
104 ViewEntry( rNewView,
105 pNewLayer ));
107 return maViewEntries.back().mpViewLayer;
110 ViewLayerSharedPtr Layer::removeView( const ViewSharedPtr& rView )
112 OSL_ASSERT( rView );
114 ViewEntryVector::iterator aIter;
115 const ViewEntryVector::iterator aEnd( maViewEntries.end() );
116 if( (aIter=std::find_if( maViewEntries.begin(),
117 aEnd,
118 boost::bind<bool>(
119 std::equal_to< ViewSharedPtr >(),
120 boost::bind( &ViewEntry::getView, _1 ),
121 boost::cref( rView )))) == aEnd )
123 // View was not added/is already removed
124 return ViewLayerSharedPtr();
127 OSL_ENSURE( std::count_if( maViewEntries.begin(),
128 aEnd,
129 boost::bind<bool>(
130 std::equal_to< ViewSharedPtr >(),
131 boost::bind( &ViewEntry::getView, _1 ),
132 boost::cref( rView ))) == 1,
133 "Layer::removeView(): view added multiple times" );
135 ViewLayerSharedPtr pRet( aIter->mpViewLayer );
136 maViewEntries.erase(aIter);
138 return pRet;
141 void Layer::viewChanged( const ViewSharedPtr& rChangedView )
143 ViewEntryVector::iterator aIter;
144 const ViewEntryVector::iterator aEnd( maViewEntries.end() );
145 if( (aIter=std::find_if( maViewEntries.begin(),
146 aEnd,
147 boost::bind<bool>(
148 std::equal_to< ViewSharedPtr >(),
149 boost::bind( &ViewEntry::getView, _1 ),
150 boost::cref( rChangedView )))) !=
151 aEnd )
153 // adapt size of given ViewLayer - background layer
154 // resizes with view.
155 if( !mbBackgroundLayer )
156 aIter->mpViewLayer->resize(maBounds);
160 void Layer::viewsChanged()
162 // adapt size of given ViewLayer - background layer
163 // resizes with view.
164 if( !mbBackgroundLayer )
166 std::for_each( maViewEntries.begin(),
167 maViewEntries.end(),
168 boost::bind( &ViewLayer::resize,
169 boost::bind( &ViewEntry::getViewLayer,
170 _1 ),
171 boost::cref(maBounds)));
175 void Layer::setShapeViews( ShapeSharedPtr const& rShape ) const
177 rShape->clearAllViewLayers();
179 std::for_each( maViewEntries.begin(),
180 maViewEntries.end(),
181 boost::bind(&Shape::addViewLayer,
182 boost::cref(rShape),
183 boost::bind(&ViewEntry::getViewLayer,
184 _1),
185 false ));
188 void Layer::setPriority( const ::basegfx::B1DRange& rPrioRange )
190 if( !mbBackgroundLayer )
192 std::for_each( maViewEntries.begin(),
193 maViewEntries.end(),
194 boost::bind( &ViewLayer::setPriority,
195 boost::bind( &ViewEntry::getViewLayer,
196 _1 ),
197 boost::cref(rPrioRange)));
201 void Layer::addUpdateRange( ::basegfx::B2DRange const& rUpdateRange )
203 // TODO(Q1): move this to B2DMultiRange
204 if( !rUpdateRange.isEmpty() )
205 maUpdateAreas.addRange( rUpdateRange );
208 void Layer::updateBounds( ShapeSharedPtr const& rShape )
210 if( !mbBackgroundLayer )
212 if( !mbBoundsDirty )
213 maNewBounds.reset();
215 maNewBounds.expand( rShape->getUpdateArea() );
218 mbBoundsDirty = true;
221 bool Layer::commitBounds()
223 mbBoundsDirty = false;
225 if( mbBackgroundLayer )
226 return false;
228 if( maNewBounds == maBounds )
229 return false;
231 maBounds = maNewBounds;
232 if( std::count_if( maViewEntries.begin(),
233 maViewEntries.end(),
234 boost::bind( &ViewLayer::resize,
235 boost::bind( &ViewEntry::getViewLayer,
236 _1 ),
237 boost::cref(maBounds)) ) == 0 )
239 return false;
242 // layer content invalid, update areas have wrong
243 // coordinates/not sensible anymore.
244 clearUpdateRanges();
246 return true;
249 void Layer::clearUpdateRanges()
251 maUpdateAreas.reset();
254 void Layer::clearContent()
256 // clear content on all view layers
257 std::for_each( maViewEntries.begin(),
258 maViewEntries.end(),
259 boost::bind(
260 &ViewLayer::clear,
261 boost::bind(
262 &ViewEntry::getViewLayer,
263 _1)));
265 // layer content cleared, update areas are not sensible
266 // anymore.
267 clearUpdateRanges();
270 class LayerEndUpdate : private boost::noncopyable
272 public:
273 LayerEndUpdate( LayerSharedPtr const& rLayer ) :
274 mpLayer( rLayer )
277 ~LayerEndUpdate() { if(mpLayer) mpLayer->endUpdate(); }
279 void dismiss() { mpLayer.reset(); }
281 private:
282 LayerSharedPtr mpLayer;
285 Layer::EndUpdater Layer::beginUpdate()
287 if( !maUpdateAreas.isEmpty() )
289 // perform proper layer update. That means, setup proper
290 // clipping, and render each shape that intersects with
291 // the calculated update area
292 ::basegfx::B2DPolyPolygon aClip( maUpdateAreas.getPolyPolygon() );
294 // actually, if there happen to be shapes with zero
295 // update area in the maUpdateAreas vector, the
296 // resulting clip polygon will be empty.
297 if( aClip.count() )
299 // set clip to all view layers
300 std::for_each( maViewEntries.begin(),
301 maViewEntries.end(),
302 boost::bind(
303 &ViewLayer::setClip,
304 boost::bind(
305 &ViewEntry::getViewLayer,
306 _1),
307 boost::cref(aClip)));
309 // clear update area on all view layers
310 std::for_each( maViewEntries.begin(),
311 maViewEntries.end(),
312 boost::bind(
313 &ViewLayer::clear,
314 boost::bind(
315 &ViewEntry::getViewLayer,
316 _1)));
318 mbClipSet = true;
322 return EndUpdater(new LayerEndUpdate(shared_from_this()));
325 void Layer::endUpdate()
327 if( mbClipSet )
329 mbClipSet = false;
331 basegfx::B2DPolyPolygon aEmptyClip;
332 std::for_each( maViewEntries.begin(),
333 maViewEntries.end(),
334 boost::bind(
335 &ViewLayer::setClip,
336 boost::bind(
337 &ViewEntry::getViewLayer,
338 _1),
339 boost::cref(aEmptyClip)));
342 clearUpdateRanges();
345 bool Layer::isInsideUpdateArea( ShapeSharedPtr const& rShape ) const
347 return maUpdateAreas.overlaps( rShape->getUpdateArea() );
350 LayerSharedPtr Layer::createBackgroundLayer( const basegfx::B2DRange& rMaxLayerBounds )
352 return LayerSharedPtr(new Layer( rMaxLayerBounds,
353 BackgroundLayer ));
356 LayerSharedPtr Layer::createLayer( const basegfx::B2DRange& rMaxLayerBounds )
358 return LayerSharedPtr( new Layer( rMaxLayerBounds ) );