1*70f497fbSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*70f497fbSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*70f497fbSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*70f497fbSAndrew Rist  * distributed with this work for additional information
6*70f497fbSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*70f497fbSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*70f497fbSAndrew Rist  * "License"); you may not use this file except in compliance
9*70f497fbSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*70f497fbSAndrew Rist  *
11*70f497fbSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*70f497fbSAndrew Rist  *
13*70f497fbSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*70f497fbSAndrew Rist  * software distributed under the License is distributed on an
15*70f497fbSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*70f497fbSAndrew Rist  * KIND, either express or implied.  See the License for the
17*70f497fbSAndrew Rist  * specific language governing permissions and limitations
18*70f497fbSAndrew Rist  * under the License.
19*70f497fbSAndrew Rist  *
20*70f497fbSAndrew Rist  *************************************************************/
21*70f497fbSAndrew Rist 
22*70f497fbSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_slideshow.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <canvas/debug.hxx>
28cdf0e10cSrcweir 
29cdf0e10cSrcweir #include <comphelper/anytostring.hxx>
30cdf0e10cSrcweir #include <cppuhelper/exc_hlp.hxx>
31cdf0e10cSrcweir 
32cdf0e10cSrcweir #include <com/sun/star/awt/MouseButton.hpp>
33cdf0e10cSrcweir #include <com/sun/star/presentation/XSlideShowView.hpp>
34cdf0e10cSrcweir 
35cdf0e10cSrcweir #include <basegfx/point/b2dpoint.hxx>
36cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygon.hxx>
37cdf0e10cSrcweir #include <cppcanvas/basegfxfactory.hxx>
38cdf0e10cSrcweir 
39cdf0e10cSrcweir #include "activity.hxx"
40cdf0e10cSrcweir #include "activitiesqueue.hxx"
41cdf0e10cSrcweir #include "slideshowcontext.hxx"
42cdf0e10cSrcweir #include "userpaintoverlay.hxx"
43cdf0e10cSrcweir #include "mouseeventhandler.hxx"
44cdf0e10cSrcweir #include "eventmultiplexer.hxx"
45cdf0e10cSrcweir #include "screenupdater.hxx"
46cdf0e10cSrcweir #include "vieweventhandler.hxx"
47cdf0e10cSrcweir 
48cdf0e10cSrcweir #include <boost/bind.hpp>
49cdf0e10cSrcweir #include <boost/noncopyable.hpp>
50cdf0e10cSrcweir #include "slide.hxx"
51cdf0e10cSrcweir #include "cursormanager.hxx"
52cdf0e10cSrcweir 
53cdf0e10cSrcweir using namespace ::com::sun::star;
54cdf0e10cSrcweir 
55cdf0e10cSrcweir namespace slideshow
56cdf0e10cSrcweir {
57cdf0e10cSrcweir     namespace internal
58cdf0e10cSrcweir     {
59cdf0e10cSrcweir         class PaintOverlayHandler : public MouseEventHandler,
60cdf0e10cSrcweir                                     public ViewEventHandler,
61cdf0e10cSrcweir 				    public UserPaintEventHandler
62cdf0e10cSrcweir         {
63cdf0e10cSrcweir         public:
PaintOverlayHandler(const RGBColor & rStrokeColor,double nStrokeWidth,ActivitiesQueue & rActivitiesQueue,ScreenUpdater & rScreenUpdater,const UnoViewContainer & rViews,Slide & rSlide,const PolyPolygonVector & rPolygons,bool bActive)64cdf0e10cSrcweir             PaintOverlayHandler( const RGBColor&          rStrokeColor,
65cdf0e10cSrcweir                                  double                   nStrokeWidth,
66cdf0e10cSrcweir                                  ActivitiesQueue&         rActivitiesQueue,
67cdf0e10cSrcweir                                  ScreenUpdater&           rScreenUpdater,
68cdf0e10cSrcweir                                  const UnoViewContainer&  rViews,
69cdf0e10cSrcweir 								 Slide&		              rSlide,
70cdf0e10cSrcweir                                  const PolyPolygonVector& rPolygons,
71cdf0e10cSrcweir 								 bool					  bActive ) :
72cdf0e10cSrcweir                 mrActivitiesQueue( rActivitiesQueue ),
73cdf0e10cSrcweir                 mrScreenUpdater( rScreenUpdater ),
74cdf0e10cSrcweir                 maViews(),
75cdf0e10cSrcweir                 maPolygons( rPolygons ),
76cdf0e10cSrcweir                 maStrokeColor( rStrokeColor ),
77cdf0e10cSrcweir                 mnStrokeWidth( nStrokeWidth ),
78cdf0e10cSrcweir                 maLastPoint(),
79cdf0e10cSrcweir                 maLastMouseDownPos(),
80cdf0e10cSrcweir                 mbIsLastPointValid( false ),
81cdf0e10cSrcweir                 mbIsLastMouseDownPosValid( false ),
82cdf0e10cSrcweir 				//handle the "remove all ink from slide" mode of erasing
83cdf0e10cSrcweir 				mbIsEraseAllModeActivated( false ),
84cdf0e10cSrcweir 				//handle the "remove stroke by stroke" mode of erasing
85cdf0e10cSrcweir 				mbIsEraseModeActivated( false ),
86cdf0e10cSrcweir 				mrSlide(rSlide),
87cdf0e10cSrcweir                 mnSize(100),
88cdf0e10cSrcweir 				mbActive( bActive )
89cdf0e10cSrcweir             {
90cdf0e10cSrcweir                 std::for_each( rViews.begin(),
91cdf0e10cSrcweir                                rViews.end(),
92cdf0e10cSrcweir                                boost::bind( &PaintOverlayHandler::viewAdded,
93cdf0e10cSrcweir                                             this,
94cdf0e10cSrcweir                                             _1 ));
95cdf0e10cSrcweir                 drawPolygons();
96cdf0e10cSrcweir             }
97cdf0e10cSrcweir 
dispose()98cdf0e10cSrcweir             virtual void dispose()
99cdf0e10cSrcweir             {
100cdf0e10cSrcweir                 maViews.clear();
101cdf0e10cSrcweir             }
102cdf0e10cSrcweir 
103cdf0e10cSrcweir             // ViewEventHandler methods
viewAdded(const UnoViewSharedPtr & rView)104cdf0e10cSrcweir             virtual void viewAdded( const UnoViewSharedPtr& rView )
105cdf0e10cSrcweir             {
106cdf0e10cSrcweir                 maViews.push_back( rView );
107cdf0e10cSrcweir             }
108cdf0e10cSrcweir 
viewRemoved(const UnoViewSharedPtr & rView)109cdf0e10cSrcweir             virtual void viewRemoved( const UnoViewSharedPtr& rView )
110cdf0e10cSrcweir             {
111cdf0e10cSrcweir                 maViews.erase( ::std::remove( maViews.begin(),
112cdf0e10cSrcweir                                               maViews.end(),
113cdf0e10cSrcweir                                               rView ) );
114cdf0e10cSrcweir             }
115cdf0e10cSrcweir 
viewChanged(const UnoViewSharedPtr &)116cdf0e10cSrcweir             virtual void viewChanged( const UnoViewSharedPtr& /*rView*/ )
117cdf0e10cSrcweir             {
118cdf0e10cSrcweir                 // TODO(F2): for persistent drawings, need to store
119cdf0e10cSrcweir                 // polygon and repaint here.
120cdf0e10cSrcweir             }
121cdf0e10cSrcweir 
viewsChanged()122cdf0e10cSrcweir             virtual void viewsChanged()
123cdf0e10cSrcweir             {
124cdf0e10cSrcweir                 // TODO(F2): for persistent drawings, need to store
125cdf0e10cSrcweir                 // polygon and repaint here.
126cdf0e10cSrcweir             }
127cdf0e10cSrcweir 
colorChanged(RGBColor const & rUserColor)128cdf0e10cSrcweir 			bool colorChanged( RGBColor const& rUserColor )
129cdf0e10cSrcweir             {
130cdf0e10cSrcweir 				mbIsLastPointValid = false;
131cdf0e10cSrcweir 				mbActive = true;
132cdf0e10cSrcweir 				this->maStrokeColor = rUserColor;
133cdf0e10cSrcweir 				this->mbIsEraseModeActivated = false;
134cdf0e10cSrcweir                 return true;
135cdf0e10cSrcweir 			}
136cdf0e10cSrcweir 
widthChanged(double nUserStrokeWidth)137cdf0e10cSrcweir             bool widthChanged( double nUserStrokeWidth )
138cdf0e10cSrcweir             {
139cdf0e10cSrcweir                 this->mnStrokeWidth = nUserStrokeWidth;
140cdf0e10cSrcweir                 mbIsEraseModeActivated = false;
141cdf0e10cSrcweir                 return true;
142cdf0e10cSrcweir             }
143cdf0e10cSrcweir 
repaintWithoutPolygons()144cdf0e10cSrcweir 			void repaintWithoutPolygons()
145cdf0e10cSrcweir 			{
146cdf0e10cSrcweir                     // must get access to the instance to erase all polygon
147cdf0e10cSrcweir 					for( UnoViewVector::iterator aIter=maViews.begin(), aEnd=maViews.end();
148cdf0e10cSrcweir 						aIter!=aEnd;
149cdf0e10cSrcweir 						++aIter )
150cdf0e10cSrcweir                     {
151cdf0e10cSrcweir 						// fully clear view content to background color
152cdf0e10cSrcweir 						//(*aIter)->getCanvas()->clear();
153cdf0e10cSrcweir 
154cdf0e10cSrcweir 						//get via SlideImpl instance the bitmap of the slide unmodified to redraw it
155cdf0e10cSrcweir 						SlideBitmapSharedPtr 		 pBitmap( mrSlide.getCurrentSlideBitmap( (*aIter) ) );
156cdf0e10cSrcweir 						::cppcanvas::CanvasSharedPtr pCanvas( (*aIter)->getCanvas() );
157cdf0e10cSrcweir 
158cdf0e10cSrcweir 						const ::basegfx::B2DHomMatrix 	aViewTransform( (*aIter)->getTransformation() );
159cdf0e10cSrcweir 						const ::basegfx::B2DPoint 		aOutPosPixel( aViewTransform * ::basegfx::B2DPoint() );
160cdf0e10cSrcweir 
161cdf0e10cSrcweir 						// setup a canvas with device coordinate space, the slide
162cdf0e10cSrcweir 						// bitmap already has the correct dimension.
163cdf0e10cSrcweir 						::cppcanvas::CanvasSharedPtr pDevicePixelCanvas( pCanvas->clone() );
164cdf0e10cSrcweir 
165cdf0e10cSrcweir 						pDevicePixelCanvas->setTransformation( ::basegfx::B2DHomMatrix() );
166cdf0e10cSrcweir 
167cdf0e10cSrcweir 						// render at given output position
168cdf0e10cSrcweir 						pBitmap->move( aOutPosPixel );
169cdf0e10cSrcweir 
170cdf0e10cSrcweir 						// clear clip (might have been changed, e.g. from comb
171cdf0e10cSrcweir 						// transition)
172cdf0e10cSrcweir 						pBitmap->clip( ::basegfx::B2DPolyPolygon() );
173cdf0e10cSrcweir 						pBitmap->draw( pDevicePixelCanvas );
174cdf0e10cSrcweir 
175cdf0e10cSrcweir 						mrScreenUpdater.notifyUpdate(*aIter,true);
176cdf0e10cSrcweir 					}
177cdf0e10cSrcweir 			}
178cdf0e10cSrcweir 
eraseAllInkChanged(bool const & rEraseAllInk)179cdf0e10cSrcweir 			bool eraseAllInkChanged( bool const& rEraseAllInk )
180cdf0e10cSrcweir             {
181cdf0e10cSrcweir 				this->mbIsEraseAllModeActivated= rEraseAllInk;
182cdf0e10cSrcweir 				// if the erase all mode is activated it will remove all ink from slide,
183cdf0e10cSrcweir 				// therefor destroy all the polygons stored
184cdf0e10cSrcweir 				if(mbIsEraseAllModeActivated)
185cdf0e10cSrcweir                 {
186cdf0e10cSrcweir 					// The Erase Mode should be desactivated
187cdf0e10cSrcweir                     mbIsEraseModeActivated = false;
188cdf0e10cSrcweir 					repaintWithoutPolygons();
189cdf0e10cSrcweir 					maPolygons.clear();
190cdf0e10cSrcweir                 }
191cdf0e10cSrcweir             mbIsEraseAllModeActivated=false;
192cdf0e10cSrcweir             return true;
193cdf0e10cSrcweir             }
194cdf0e10cSrcweir 
eraseInkWidthChanged(sal_Int32 rEraseInkSize)195cdf0e10cSrcweir             bool eraseInkWidthChanged( sal_Int32 rEraseInkSize )
196cdf0e10cSrcweir             {
197cdf0e10cSrcweir                 // Change the size
198cdf0e10cSrcweir                 this->mnSize=rEraseInkSize;
199cdf0e10cSrcweir                 // Changed to mode Erase
200cdf0e10cSrcweir                 this->mbIsEraseModeActivated = true;
201cdf0e10cSrcweir                 return true;
202cdf0e10cSrcweir             }
203cdf0e10cSrcweir 
switchPenMode()204cdf0e10cSrcweir             bool switchPenMode()
205cdf0e10cSrcweir             {
206cdf0e10cSrcweir 				mbIsLastPointValid = false;
207cdf0e10cSrcweir 				mbActive = true;
208cdf0e10cSrcweir                 this->mbIsEraseModeActivated = false;
209cdf0e10cSrcweir                 return true;
210cdf0e10cSrcweir             }
211cdf0e10cSrcweir 
switchEraserMode()212cdf0e10cSrcweir             bool switchEraserMode()
213cdf0e10cSrcweir             {
214cdf0e10cSrcweir 				mbIsLastPointValid = false;
215cdf0e10cSrcweir 				mbActive = true;
216cdf0e10cSrcweir                 this->mbIsEraseModeActivated = true;
217cdf0e10cSrcweir                 return true;
218cdf0e10cSrcweir             }
219cdf0e10cSrcweir 
disable()220cdf0e10cSrcweir             bool disable()
221cdf0e10cSrcweir             {
222cdf0e10cSrcweir 				mbIsLastPointValid = false;
223cdf0e10cSrcweir                 mbIsLastMouseDownPosValid = false;
224cdf0e10cSrcweir 				mbActive = false;
225cdf0e10cSrcweir                 return true;
226cdf0e10cSrcweir             }
227cdf0e10cSrcweir 
228cdf0e10cSrcweir             //Draw all registered polygons.
drawPolygons()229cdf0e10cSrcweir             void drawPolygons()
230cdf0e10cSrcweir             {
231cdf0e10cSrcweir                 for( PolyPolygonVector::iterator aIter=maPolygons.begin(), aEnd=maPolygons.end();
232cdf0e10cSrcweir                                      aIter!=aEnd;
233cdf0e10cSrcweir                                      ++aIter )
234cdf0e10cSrcweir                 {
235cdf0e10cSrcweir                     (*aIter)->draw();
236cdf0e10cSrcweir                 }
237cdf0e10cSrcweir                 // screen update necessary to show painting
238cdf0e10cSrcweir                 mrScreenUpdater.notifyUpdate();
239cdf0e10cSrcweir             }
240cdf0e10cSrcweir 
241cdf0e10cSrcweir             //Retrieve all registered polygons.
getPolygons()242cdf0e10cSrcweir             PolyPolygonVector getPolygons()
243cdf0e10cSrcweir             {
244cdf0e10cSrcweir                 return maPolygons;
245cdf0e10cSrcweir             }
246cdf0e10cSrcweir 
247cdf0e10cSrcweir             // MouseEventHandler methods
handleMousePressed(const awt::MouseEvent & e)248cdf0e10cSrcweir             virtual bool handleMousePressed( const awt::MouseEvent& e )
249cdf0e10cSrcweir             {
250cdf0e10cSrcweir 				if( !mbActive )
251cdf0e10cSrcweir 					return false;
252cdf0e10cSrcweir 
253cdf0e10cSrcweir                 if (e.Buttons == awt::MouseButton::RIGHT)
254cdf0e10cSrcweir                 {
255cdf0e10cSrcweir                     mbIsLastPointValid = false;
256cdf0e10cSrcweir                     return false;
257cdf0e10cSrcweir                 }
258cdf0e10cSrcweir 
259cdf0e10cSrcweir                 if (e.Buttons != awt::MouseButton::LEFT)
260cdf0e10cSrcweir 					return false;
261cdf0e10cSrcweir 
262cdf0e10cSrcweir                 maLastMouseDownPos.setX( e.X );
263cdf0e10cSrcweir                 maLastMouseDownPos.setY( e.Y );
264cdf0e10cSrcweir                 mbIsLastMouseDownPosValid = true;
265cdf0e10cSrcweir 
266cdf0e10cSrcweir                 // eat mouse click (though we don't process it
267cdf0e10cSrcweir                 // _directly_, it enables the drag mode
268cdf0e10cSrcweir                 return true;
269cdf0e10cSrcweir             }
270cdf0e10cSrcweir 
handleMouseReleased(const awt::MouseEvent & e)271cdf0e10cSrcweir             virtual bool handleMouseReleased( const awt::MouseEvent& e )
272cdf0e10cSrcweir             {
273cdf0e10cSrcweir 				if( !mbActive )
274cdf0e10cSrcweir 					return false;
275cdf0e10cSrcweir 
276cdf0e10cSrcweir                 if (e.Buttons == awt::MouseButton::RIGHT)
277cdf0e10cSrcweir                 {
278cdf0e10cSrcweir                     mbIsLastPointValid = false;
279cdf0e10cSrcweir                     return false;
280cdf0e10cSrcweir                 }
281cdf0e10cSrcweir 
282cdf0e10cSrcweir                 if (e.Buttons != awt::MouseButton::LEFT)
283cdf0e10cSrcweir                     return false;
284cdf0e10cSrcweir 
285cdf0e10cSrcweir                 // check, whether up- and down press are on exactly
286cdf0e10cSrcweir                 // the same pixel. If that's the case, ignore the
287cdf0e10cSrcweir                 // click, and pass on the event to low-prio
288cdf0e10cSrcweir                 // handlers. This effectively permits effect
289cdf0e10cSrcweir                 // advancements via clicks also when user paint is
290cdf0e10cSrcweir                 // enabled.
291cdf0e10cSrcweir                 if( mbIsLastMouseDownPosValid &&
292cdf0e10cSrcweir                     ::basegfx::B2DPoint( e.X,
293cdf0e10cSrcweir                                          e.Y ) == maLastMouseDownPos )
294cdf0e10cSrcweir                 {
295cdf0e10cSrcweir                     mbIsLastMouseDownPosValid = false;
296cdf0e10cSrcweir                     return false;
297cdf0e10cSrcweir                 }
298cdf0e10cSrcweir 
299cdf0e10cSrcweir                 // invalidate, next downpress will have to start a new
300cdf0e10cSrcweir                 // polygon.
301cdf0e10cSrcweir                 mbIsLastPointValid = false;
302cdf0e10cSrcweir 
303cdf0e10cSrcweir                 // eat mouse click (though we don't process it
304cdf0e10cSrcweir                 // _directly_, it enables the drag mode
305cdf0e10cSrcweir                 return true;
306cdf0e10cSrcweir             }
307cdf0e10cSrcweir 
handleMouseEntered(const awt::MouseEvent & e)308cdf0e10cSrcweir             virtual bool handleMouseEntered( const awt::MouseEvent& e )
309cdf0e10cSrcweir             {
310cdf0e10cSrcweir 				if( !mbActive )
311cdf0e10cSrcweir 					return false;
312cdf0e10cSrcweir 
313cdf0e10cSrcweir                 mbIsLastPointValid = true;
314cdf0e10cSrcweir                 maLastPoint.setX( e.X );
315cdf0e10cSrcweir                 maLastPoint.setY( e.Y );
316cdf0e10cSrcweir 
317cdf0e10cSrcweir                 return true;
318cdf0e10cSrcweir             }
319cdf0e10cSrcweir 
handleMouseExited(const awt::MouseEvent &)320cdf0e10cSrcweir             virtual bool handleMouseExited( const awt::MouseEvent& )
321cdf0e10cSrcweir             {
322cdf0e10cSrcweir 				if( !mbActive )
323cdf0e10cSrcweir 					return false;
324cdf0e10cSrcweir 
325cdf0e10cSrcweir 				mbIsLastPointValid = false;
326cdf0e10cSrcweir                 mbIsLastMouseDownPosValid = false;
327cdf0e10cSrcweir 
328cdf0e10cSrcweir                 return true;
329cdf0e10cSrcweir             }
330cdf0e10cSrcweir 
handleMouseDragged(const awt::MouseEvent & e)331cdf0e10cSrcweir             virtual bool handleMouseDragged( const awt::MouseEvent& e )
332cdf0e10cSrcweir             {
333cdf0e10cSrcweir 				if( !mbActive )
334cdf0e10cSrcweir 					return false;
335cdf0e10cSrcweir 
336cdf0e10cSrcweir                 if (e.Buttons == awt::MouseButton::RIGHT)
337cdf0e10cSrcweir                 {
338cdf0e10cSrcweir                     mbIsLastPointValid = false;
339cdf0e10cSrcweir                     return false;
340cdf0e10cSrcweir                 }
341cdf0e10cSrcweir 
342cdf0e10cSrcweir 				if(mbIsEraseModeActivated)
343cdf0e10cSrcweir                 {
344cdf0e10cSrcweir 					//define the last point as an object
345cdf0e10cSrcweir 					//we suppose that there's no way this point could be valid
346cdf0e10cSrcweir 					::basegfx::B2DPolygon aPoly;
347cdf0e10cSrcweir 
348cdf0e10cSrcweir                     maLastPoint.setX( e.X-mnSize );
349cdf0e10cSrcweir                     maLastPoint.setY( e.Y-mnSize );
350cdf0e10cSrcweir 
351cdf0e10cSrcweir                     aPoly.append( maLastPoint );
352cdf0e10cSrcweir 
353cdf0e10cSrcweir                     maLastPoint.setX( e.X-mnSize );
354cdf0e10cSrcweir                     maLastPoint.setY( e.Y+mnSize );
355cdf0e10cSrcweir 
356cdf0e10cSrcweir                     aPoly.append( maLastPoint );
357cdf0e10cSrcweir                     maLastPoint.setX( e.X+mnSize );
358cdf0e10cSrcweir                     maLastPoint.setY( e.Y+mnSize );
359cdf0e10cSrcweir 
360cdf0e10cSrcweir                     aPoly.append( maLastPoint );
361cdf0e10cSrcweir                     maLastPoint.setX( e.X+mnSize );
362cdf0e10cSrcweir                     maLastPoint.setY( e.Y-mnSize );
363cdf0e10cSrcweir 
364cdf0e10cSrcweir                     aPoly.append( maLastPoint );
365cdf0e10cSrcweir                     maLastPoint.setX( e.X-mnSize );
366cdf0e10cSrcweir                     maLastPoint.setY( e.Y-mnSize );
367cdf0e10cSrcweir 
368cdf0e10cSrcweir 					aPoly.append( maLastPoint );
369cdf0e10cSrcweir 
370cdf0e10cSrcweir 					//now we have defined a Polygon that is closed
371cdf0e10cSrcweir 
372cdf0e10cSrcweir 					//The point is to redraw the LastPoint the way it was originally on the bitmap,
373cdf0e10cSrcweir 					//of the slide
374cdf0e10cSrcweir 		    for( UnoViewVector::iterator aIter=maViews.begin(), aEnd=maViews.end();
375cdf0e10cSrcweir 						aIter!=aEnd;
376cdf0e10cSrcweir 						++aIter )
377cdf0e10cSrcweir                     {
378cdf0e10cSrcweir 
379cdf0e10cSrcweir 						//get via SlideImpl instance the bitmap of the slide unmodified to redraw it
380cdf0e10cSrcweir 						SlideBitmapSharedPtr 		 pBitmap( mrSlide.getCurrentSlideBitmap( (*aIter) ) );
381cdf0e10cSrcweir 						::cppcanvas::CanvasSharedPtr pCanvas( (*aIter)->getCanvas() );
382cdf0e10cSrcweir 
383cdf0e10cSrcweir 						::basegfx::B2DHomMatrix 	aViewTransform( (*aIter)->getTransformation() );
384cdf0e10cSrcweir 						const ::basegfx::B2DPoint 		aOutPosPixel( aViewTransform * ::basegfx::B2DPoint() );
385cdf0e10cSrcweir 
386cdf0e10cSrcweir 						// setup a canvas with device coordinate space, the slide
387cdf0e10cSrcweir 						// bitmap already has the correct dimension.
388cdf0e10cSrcweir 						::cppcanvas::CanvasSharedPtr pDevicePixelCanvas( pCanvas->clone() );
389cdf0e10cSrcweir 
390cdf0e10cSrcweir 						pDevicePixelCanvas->setTransformation( ::basegfx::B2DHomMatrix() );
391cdf0e10cSrcweir 
392cdf0e10cSrcweir 						// render at given output position
393cdf0e10cSrcweir 						pBitmap->move( aOutPosPixel );
394cdf0e10cSrcweir 
395cdf0e10cSrcweir                         ::basegfx::B2DPolyPolygon aPolyPoly=::basegfx::B2DPolyPolygon(aPoly);
396cdf0e10cSrcweir                         aViewTransform.translate(-aOutPosPixel.getX(), -aOutPosPixel.getY());
397cdf0e10cSrcweir                         aPolyPoly.transform(aViewTransform);
398cdf0e10cSrcweir 						// set clip so that we just redraw a part of the canvas
399cdf0e10cSrcweir 						pBitmap->clip(aPolyPoly);
400cdf0e10cSrcweir 						pBitmap->draw( pDevicePixelCanvas );
401cdf0e10cSrcweir 
402cdf0e10cSrcweir 						mrScreenUpdater.notifyUpdate(*aIter,true);
403cdf0e10cSrcweir 					}
404cdf0e10cSrcweir 
405cdf0e10cSrcweir 		}
406cdf0e10cSrcweir                 else
407cdf0e10cSrcweir                 {
408cdf0e10cSrcweir 					if( !mbIsLastPointValid )
409cdf0e10cSrcweir 					{
410cdf0e10cSrcweir 						mbIsLastPointValid = true;
411cdf0e10cSrcweir 						maLastPoint.setX( e.X );
412cdf0e10cSrcweir 						maLastPoint.setY( e.Y );
413cdf0e10cSrcweir 					}
414cdf0e10cSrcweir 					else
415cdf0e10cSrcweir 					{
416cdf0e10cSrcweir 						::basegfx::B2DPolygon aPoly;
417cdf0e10cSrcweir 						aPoly.append( maLastPoint );
418cdf0e10cSrcweir 
419cdf0e10cSrcweir 						maLastPoint.setX( e.X );
420cdf0e10cSrcweir 						maLastPoint.setY( e.Y );
421cdf0e10cSrcweir 
422cdf0e10cSrcweir 						aPoly.append( maLastPoint );
423cdf0e10cSrcweir 
424cdf0e10cSrcweir 						// paint to all views
425cdf0e10cSrcweir 						for( UnoViewVector::iterator aIter=maViews.begin(), aEnd=maViews.end();
426cdf0e10cSrcweir                              aIter!=aEnd;
427cdf0e10cSrcweir                              ++aIter )
428cdf0e10cSrcweir 						{
429cdf0e10cSrcweir 							::cppcanvas::PolyPolygonSharedPtr pPolyPoly(
430cdf0e10cSrcweir                                 ::cppcanvas::BaseGfxFactory::getInstance().createPolyPolygon( (*aIter)->getCanvas(),
431cdf0e10cSrcweir                                                                                               aPoly ) );
432cdf0e10cSrcweir 
433cdf0e10cSrcweir 							if( pPolyPoly )
434cdf0e10cSrcweir 							{
435cdf0e10cSrcweir 								pPolyPoly->setStrokeWidth(mnStrokeWidth);
436cdf0e10cSrcweir                                 pPolyPoly->setRGBALineColor( maStrokeColor.getIntegerColor() );
437cdf0e10cSrcweir 								pPolyPoly->draw();
438cdf0e10cSrcweir                                 maPolygons.push_back(pPolyPoly);
439cdf0e10cSrcweir                             }
440cdf0e10cSrcweir 						}
441cdf0e10cSrcweir 
442cdf0e10cSrcweir 						// screen update necessary to show painting
443cdf0e10cSrcweir 						mrScreenUpdater.notifyUpdate();
444cdf0e10cSrcweir 					}
445cdf0e10cSrcweir 				}
446cdf0e10cSrcweir                 // mouse events captured
447cdf0e10cSrcweir                 return true;
448cdf0e10cSrcweir             }
449cdf0e10cSrcweir 
handleMouseMoved(const awt::MouseEvent &)450cdf0e10cSrcweir             virtual bool handleMouseMoved( const awt::MouseEvent& /*e*/ )
451cdf0e10cSrcweir             {
452cdf0e10cSrcweir                 // not used here
453cdf0e10cSrcweir                 return false; // did not handle the event
454cdf0e10cSrcweir             }
455cdf0e10cSrcweir 
456cdf0e10cSrcweir 
update_settings(bool bUserPaintEnabled,RGBColor const & aUserPaintColor,double dUserPaintStrokeWidth)457cdf0e10cSrcweir 			void update_settings( bool bUserPaintEnabled, RGBColor const& aUserPaintColor, double dUserPaintStrokeWidth )
458cdf0e10cSrcweir 			{
459cdf0e10cSrcweir 				maStrokeColor = aUserPaintColor;
460cdf0e10cSrcweir 				mnStrokeWidth = dUserPaintStrokeWidth;
461cdf0e10cSrcweir 				mbActive = bUserPaintEnabled;
462cdf0e10cSrcweir 				if( !mbActive )
463cdf0e10cSrcweir 					disable();
464cdf0e10cSrcweir 			}
465cdf0e10cSrcweir 
466cdf0e10cSrcweir         private:
467cdf0e10cSrcweir             ActivitiesQueue&        mrActivitiesQueue;
468cdf0e10cSrcweir             ScreenUpdater&          mrScreenUpdater;
469cdf0e10cSrcweir             UnoViewVector           maViews;
470cdf0e10cSrcweir             PolyPolygonVector 	    maPolygons;
471cdf0e10cSrcweir 			RGBColor                maStrokeColor;
472cdf0e10cSrcweir             double                  mnStrokeWidth;
473cdf0e10cSrcweir             basegfx::B2DPoint       maLastPoint;
474cdf0e10cSrcweir             basegfx::B2DPoint       maLastMouseDownPos;
475cdf0e10cSrcweir             bool                    mbIsLastPointValid;
476cdf0e10cSrcweir             bool                    mbIsLastMouseDownPosValid;
477cdf0e10cSrcweir 			// added bool for erasing purpose :
478cdf0e10cSrcweir 			bool					mbIsEraseAllModeActivated;
479cdf0e10cSrcweir 			bool					mbIsEraseModeActivated;
480cdf0e10cSrcweir 			Slide&					mrSlide;
481cdf0e10cSrcweir             sal_Int32               mnSize;
482cdf0e10cSrcweir 			bool					mbActive;
483cdf0e10cSrcweir         };
484cdf0e10cSrcweir 
create(const RGBColor & rStrokeColor,double nStrokeWidth,const SlideShowContext & rContext,const PolyPolygonVector & rPolygons,bool bActive)485cdf0e10cSrcweir         UserPaintOverlaySharedPtr UserPaintOverlay::create( const RGBColor&          rStrokeColor,
486cdf0e10cSrcweir                                                             double                   nStrokeWidth,
487cdf0e10cSrcweir                                                             const SlideShowContext&  rContext,
488cdf0e10cSrcweir                                                             const PolyPolygonVector& rPolygons,
489cdf0e10cSrcweir 															bool					 bActive )
490cdf0e10cSrcweir         {
491cdf0e10cSrcweir             UserPaintOverlaySharedPtr pRet( new UserPaintOverlay( rStrokeColor,
492cdf0e10cSrcweir                                                                   nStrokeWidth,
493cdf0e10cSrcweir                                                                   rContext,
494cdf0e10cSrcweir                                                                   rPolygons,
495cdf0e10cSrcweir 																  bActive));
496cdf0e10cSrcweir 
497cdf0e10cSrcweir             return pRet;
498cdf0e10cSrcweir         }
499cdf0e10cSrcweir 
UserPaintOverlay(const RGBColor & rStrokeColor,double nStrokeWidth,const SlideShowContext & rContext,const PolyPolygonVector & rPolygons,bool bActive)500cdf0e10cSrcweir         UserPaintOverlay::UserPaintOverlay( const RGBColor&          rStrokeColor,
501cdf0e10cSrcweir                                             double                   nStrokeWidth,
502cdf0e10cSrcweir                                             const SlideShowContext&  rContext,
503cdf0e10cSrcweir                                             const PolyPolygonVector& rPolygons,
504cdf0e10cSrcweir 											bool					 bActive ) :
505cdf0e10cSrcweir             mpHandler( new PaintOverlayHandler( rStrokeColor,
506cdf0e10cSrcweir                                                 nStrokeWidth,
507cdf0e10cSrcweir                                                 rContext.mrActivitiesQueue,
508cdf0e10cSrcweir                                                 rContext.mrScreenUpdater,
509cdf0e10cSrcweir                                                 rContext.mrViewContainer,
510cdf0e10cSrcweir                                                 //adding a link to Slide
511cdf0e10cSrcweir                                                 dynamic_cast<Slide&>(rContext.mrCursorManager),
512cdf0e10cSrcweir                                                 rPolygons, bActive )),
513cdf0e10cSrcweir             mrMultiplexer( rContext.mrEventMultiplexer )
514cdf0e10cSrcweir         {
515cdf0e10cSrcweir             mrMultiplexer.addClickHandler( mpHandler, 3.0 );
516cdf0e10cSrcweir             mrMultiplexer.addMouseMoveHandler( mpHandler, 3.0 );
517cdf0e10cSrcweir             mrMultiplexer.addViewHandler( mpHandler );
518cdf0e10cSrcweir 			mrMultiplexer.addUserPaintHandler(mpHandler);
519cdf0e10cSrcweir         }
520cdf0e10cSrcweir 
getPolygons()521cdf0e10cSrcweir         PolyPolygonVector UserPaintOverlay::getPolygons()
522cdf0e10cSrcweir         {
523cdf0e10cSrcweir             return mpHandler->getPolygons();
524cdf0e10cSrcweir         }
525cdf0e10cSrcweir 
drawPolygons()526cdf0e10cSrcweir         void UserPaintOverlay::drawPolygons()
527cdf0e10cSrcweir         {
528cdf0e10cSrcweir             mpHandler->drawPolygons();
529cdf0e10cSrcweir         }
530cdf0e10cSrcweir 
update_settings(bool bUserPaintEnabled,RGBColor const & aUserPaintColor,double dUserPaintStrokeWidth)531cdf0e10cSrcweir 		void UserPaintOverlay::update_settings( bool bUserPaintEnabled, RGBColor const& aUserPaintColor, double dUserPaintStrokeWidth )
532cdf0e10cSrcweir 		{
533cdf0e10cSrcweir 			mpHandler->update_settings( bUserPaintEnabled, aUserPaintColor, dUserPaintStrokeWidth );
534cdf0e10cSrcweir 		}
535cdf0e10cSrcweir 
536cdf0e10cSrcweir 
~UserPaintOverlay()537cdf0e10cSrcweir         UserPaintOverlay::~UserPaintOverlay()
538cdf0e10cSrcweir         {
539cdf0e10cSrcweir             try
540cdf0e10cSrcweir             {
541cdf0e10cSrcweir                 mrMultiplexer.removeMouseMoveHandler( mpHandler );
542cdf0e10cSrcweir                 mrMultiplexer.removeClickHandler( mpHandler );
543cdf0e10cSrcweir                 mrMultiplexer.removeViewHandler( mpHandler );
544cdf0e10cSrcweir                 mpHandler->dispose();
545cdf0e10cSrcweir             }
546cdf0e10cSrcweir             catch (uno::Exception &)
547cdf0e10cSrcweir             {
548cdf0e10cSrcweir                 OSL_ENSURE( false, rtl::OUStringToOString(
549cdf0e10cSrcweir                                 comphelper::anyToString(
550cdf0e10cSrcweir                                     cppu::getCaughtException() ),
551cdf0e10cSrcweir                                 RTL_TEXTENCODING_UTF8 ).getStr() );
552cdf0e10cSrcweir             }
553cdf0e10cSrcweir         }
554cdf0e10cSrcweir     }
555cdf0e10cSrcweir }
556