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