LibreOffice Module slideshow (master) 1
userpaintoverlay.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20
21#include <com/sun/star/awt/MouseButton.hpp>
22#include <com/sun/star/awt/MouseEvent.hpp>
23
29
30#include <slideshowcontext.hxx>
31#include "userpaintoverlay.hxx"
32#include <mouseeventhandler.hxx>
33#include <eventmultiplexer.hxx>
34#include <screenupdater.hxx>
35#include <vieweventhandler.hxx>
36
37#include <slide.hxx>
38#include <cursormanager.hxx>
39
40using namespace ::com::sun::star;
41
42namespace slideshow::internal
43{
45 public ViewEventHandler,
47 {
48 public:
49 PaintOverlayHandler( const RGBColor& rStrokeColor,
50 double nStrokeWidth,
51 ScreenUpdater& rScreenUpdater,
52 const UnoViewContainer& rViews,
53 Slide& rSlide,
54 PolyPolygonVector&& rPolygons,
55 bool bActive ) :
56 mrScreenUpdater( rScreenUpdater ),
57 maViews(),
58 maPolygons( std::move(rPolygons) ),
59 maStrokeColor( rStrokeColor ),
60 mnStrokeWidth( nStrokeWidth ),
63 mbIsLastPointValid( false ),
65 //handle the "remove all ink from slide" mode of erasing
67 //handle the "remove stroke by stroke" mode of erasing
69 mrSlide(rSlide),
70 mnSize(100),
71 mbActive( bActive )
72 {
73 for( const auto& rView : rViews )
74 viewAdded( rView );
75
77 }
78
79 void dispose()
80 {
81 maViews.clear();
82 }
83
84 // ViewEventHandler methods
85 virtual void viewAdded( const UnoViewSharedPtr& rView ) override
86 {
87 maViews.push_back( rView );
88 }
89
90 virtual void viewRemoved( const UnoViewSharedPtr& rView ) override
91 {
92 maViews.erase( ::std::remove( maViews.begin(),
93 maViews.end(),
94 rView ) );
95 }
96
97 virtual void viewChanged( const UnoViewSharedPtr& /*rView*/ ) override
98 {
99 // TODO(F2): for persistent drawings, need to store
100 // polygon and repaint here.
101 }
102
103 virtual void viewsChanged() override
104 {
105 // TODO(F2): for persistent drawings, need to store
106 // polygon and repaint here.
107 }
108
109 bool colorChanged( RGBColor const& rUserColor ) override
110 {
111 mbIsLastPointValid = false;
112 mbActive = true;
113 maStrokeColor = rUserColor;
115 return true;
116 }
117
118 bool widthChanged( double nUserStrokeWidth ) override
119 {
120 mnStrokeWidth = nUserStrokeWidth;
122 return true;
123 }
124
126 {
127 // must get access to the instance to erase all polygon
128 for( const auto& rxView : maViews )
129 {
130 // fully clear view content to background color
131 //rxView->getCanvas()->clear();
132
133 //get via SlideImpl instance the bitmap of the slide unmodified to redraw it
135 ::cppcanvas::CanvasSharedPtr pCanvas( rxView->getCanvas() );
136
137 const ::basegfx::B2DHomMatrix aViewTransform( rxView->getTransformation() );
138 const ::basegfx::B2DPoint aOutPosPixel( aViewTransform * ::basegfx::B2DPoint() );
139
140 // setup a canvas with device coordinate space, the slide
141 // bitmap already has the correct dimension.
142 ::cppcanvas::CanvasSharedPtr pDevicePixelCanvas( pCanvas->clone() );
143
144 pDevicePixelCanvas->setTransformation( ::basegfx::B2DHomMatrix() );
145
146 // render at given output position
147 pBitmap->move( aOutPosPixel );
148
149 // clear clip (might have been changed, e.g. from comb
150 // transition)
151 pBitmap->clip( ::basegfx::B2DPolyPolygon() );
152 pBitmap->draw( pDevicePixelCanvas );
153
154 mrScreenUpdater.notifyUpdate(rxView,true);
155 }
156 }
157
158 bool eraseAllInkChanged( bool bEraseAllInk ) override
159 {
160 mbIsEraseAllModeActivated = bEraseAllInk;
161 // if the erase all mode is activated it will remove all ink from slide,
162 // therefore destroy all the polygons stored
164 {
165 // The Erase Mode should be deactivated
168 maPolygons.clear();
169 }
171 return true;
172 }
173
174 bool eraseInkWidthChanged( sal_Int32 rEraseInkSize ) override
175 {
176 // Change the size
177 mnSize=rEraseInkSize;
178 // Changed to mode Erase
180 return true;
181 }
182
183 bool switchPenMode() override
184 {
185 mbIsLastPointValid = false;
186 mbActive = true;
188 return true;
189 }
190
191 bool switchEraserMode() override
192 {
193 mbIsLastPointValid = false;
194 mbActive = true;
196 return true;
197 }
198
199 bool disable() override
200 {
201 mbIsLastPointValid = false;
203 mbActive = false;
204 return true;
205 }
206
207 //Draw all registered polygons.
209 {
210 for( const auto& rxPolygon : maPolygons )
211 {
212 rxPolygon->draw();
213 }
214 // screen update necessary to show painting
216 }
217
218 //Retrieve all registered polygons.
220 {
221 return maPolygons;
222 }
223
224 // MouseEventHandler methods
225 virtual bool handleMousePressed( const awt::MouseEvent& e ) override
226 {
227 if( !mbActive )
228 return false;
229
230 if (e.Buttons == awt::MouseButton::RIGHT)
231 {
232 mbIsLastPointValid = false;
233 return false;
234 }
235
236 if (e.Buttons != awt::MouseButton::LEFT)
237 return false;
238
242
243 // eat mouse click (though we don't process it
244 // _directly_, it enables the drag mode
245 return true;
246 }
247
248 virtual bool handleMouseReleased( const awt::MouseEvent& e ) override
249 {
250 if( !mbActive )
251 return false;
252
253 if (e.Buttons == awt::MouseButton::RIGHT)
254 {
255 mbIsLastPointValid = false;
256 return false;
257 }
258
259 if (e.Buttons != awt::MouseButton::LEFT)
260 return false;
261
262 // check, whether up- and down press are on exactly
263 // the same pixel. If that's the case, ignore the
264 // click, and pass on the event to low-prio
265 // handlers. This effectively permits effect
266 // advancements via clicks also when user paint is
267 // enabled.
270 e.Y ) == maLastMouseDownPos )
271 {
273 return false;
274 }
275
276 // invalidate, next downpress will have to start a new
277 // polygon.
278 mbIsLastPointValid = false;
279
280 // eat mouse click (though we don't process it
281 // _directly_, it enables the drag mode
282 return true;
283 }
284
285 virtual bool handleMouseDragged( const awt::MouseEvent& e ) override
286 {
287 if( !mbActive )
288 return false;
289
290 if (e.Buttons == awt::MouseButton::RIGHT)
291 {
292 mbIsLastPointValid = false;
293 return false;
294 }
295
297 {
298 //define the last point as an object
299 //we suppose that there's no way this point could be valid
301
302 maLastPoint.setX( e.X-mnSize );
303 maLastPoint.setY( e.Y-mnSize );
304
305 aPoly.append( maLastPoint );
306
307 maLastPoint.setX( e.X-mnSize );
308 maLastPoint.setY( e.Y+mnSize );
309
310 aPoly.append( maLastPoint );
311 maLastPoint.setX( e.X+mnSize );
312 maLastPoint.setY( e.Y+mnSize );
313
314 aPoly.append( maLastPoint );
315 maLastPoint.setX( e.X+mnSize );
316 maLastPoint.setY( e.Y-mnSize );
317
318 aPoly.append( maLastPoint );
319 maLastPoint.setX( e.X-mnSize );
320 maLastPoint.setY( e.Y-mnSize );
321
322 aPoly.append( maLastPoint );
323
324 //now we have defined a Polygon that is closed
325
326 //The point is to redraw the LastPoint the way it was originally on the bitmap,
327 //of the slide
328 for (const auto& rxView : maViews)
329 {
330
331 //get via SlideImpl instance the bitmap of the slide unmodified to redraw it
333 ::cppcanvas::CanvasSharedPtr pCanvas( rxView->getCanvas() );
334
335 ::basegfx::B2DHomMatrix aViewTransform( rxView->getTransformation() );
336 const ::basegfx::B2DPoint aOutPosPixel( aViewTransform * ::basegfx::B2DPoint() );
337
338 // setup a canvas with device coordinate space, the slide
339 // bitmap already has the correct dimension.
340 ::cppcanvas::CanvasSharedPtr pDevicePixelCanvas( pCanvas->clone() );
341
342 pDevicePixelCanvas->setTransformation( ::basegfx::B2DHomMatrix() );
343
344 // render at given output position
345 pBitmap->move( aOutPosPixel );
346
347 ::basegfx::B2DPolyPolygon aPolyPoly(aPoly);
348 aViewTransform.translate(-aOutPosPixel.getX(), -aOutPosPixel.getY());
349 aPolyPoly.transform(aViewTransform);
350 // set clip so that we just redraw a part of the canvas
351 pBitmap->clip(aPolyPoly);
352 pBitmap->draw( pDevicePixelCanvas );
353
354 mrScreenUpdater.notifyUpdate(rxView,true);
355 }
356
357 }
358 else
359 {
360 if( !mbIsLastPointValid )
361 {
362 mbIsLastPointValid = true;
363 maLastPoint.setX( e.X );
364 maLastPoint.setY( e.Y );
365 }
366 else
367 {
369 aPoly.append( maLastPoint );
370
371 maLastPoint.setX( e.X );
372 maLastPoint.setY( e.Y );
373
374 aPoly.append( maLastPoint );
375
376 // paint to all views
377 for (const auto& rxView : maViews)
378 {
381 aPoly ) );
382
383 if( pPolyPoly )
384 {
385 pPolyPoly->setStrokeWidth(mnStrokeWidth);
386 pPolyPoly->setRGBALineColor( maStrokeColor.getIntegerColor() );
387 pPolyPoly->draw();
388 maPolygons.push_back(pPolyPoly);
389 }
390 }
391
392 // screen update necessary to show painting
394 }
395 }
396 // mouse events captured
397 return true;
398 }
399
400 virtual bool handleMouseMoved( const awt::MouseEvent& /*e*/ ) override
401 {
402 // not used here
403 return false; // did not handle the event
404 }
405
406 private:
416 // added bool for erasing purpose :
420 sal_Int32 mnSize;
422 };
423
425 double nStrokeWidth,
426 const SlideShowContext& rContext,
427 PolyPolygonVector&& rPolygons,
428 bool bActive )
429 {
430 UserPaintOverlaySharedPtr pRet( new UserPaintOverlay( rStrokeColor,
431 nStrokeWidth,
432 rContext,
433 std::move(rPolygons),
434 bActive));
435
436 return pRet;
437 }
438
440 double nStrokeWidth,
441 const SlideShowContext& rContext,
442 PolyPolygonVector&& rPolygons,
443 bool bActive ) :
445 nStrokeWidth,
446 rContext.mrScreenUpdater,
447 rContext.mrViewContainer,
448 //adding a link to Slide
449 dynamic_cast<Slide&>(rContext.mrCursorManager),
450 std::move(rPolygons), bActive )),
452 {
457 }
458
460 {
461 return mpHandler->getPolygons();
462 }
463
465 {
466 mpHandler->drawPolygons();
467 }
468
470 {
471 try
472 {
476 mpHandler->dispose();
477 }
478 catch (const uno::Exception&)
479 {
480 TOOLS_WARN_EXCEPTION("slideshow", "");
481 }
482 }
483}
484
485/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void translate(double fX, double fY)
void transform(const basegfx::B2DHomMatrix &rMatrix)
void append(const basegfx::B2DPoint &rPoint, sal_uInt32 nCount)
void setY(TYPE fY)
void setX(TYPE fX)
static PolyPolygonSharedPtr createPolyPolygon(const CanvasSharedPtr &, const ::basegfx::B2DPolygon &rPoly)
void removeClickHandler(const MouseEventHandlerSharedPtr &rHandler)
void removeMouseMoveHandler(const MouseEventHandlerSharedPtr &rHandler)
void addClickHandler(const MouseEventHandlerSharedPtr &rHandler, double nPriority)
Register a mouse handler that is called on mouse click.
void addMouseMoveHandler(const MouseEventHandlerSharedPtr &rHandler, double nPriority)
Register a mouse handler that is called for mouse moves.
void removeViewHandler(const ViewEventHandlerWeakPtr &rHandler)
void addViewHandler(const ViewEventHandlerWeakPtr &rHandler)
Register an event handler that will be called when views are changed.
void addUserPaintHandler(const UserPaintEventHandlerSharedPtr &rHandler)
Register an event handler that will be called when user paint parameters change.
Interface for handling mouse events.
virtual void viewRemoved(const UnoViewSharedPtr &rView) override
Notify removed view.
bool eraseInkWidthChanged(sal_Int32 rEraseInkSize) override
PaintOverlayHandler(const RGBColor &rStrokeColor, double nStrokeWidth, ScreenUpdater &rScreenUpdater, const UnoViewContainer &rViews, Slide &rSlide, PolyPolygonVector &&rPolygons, bool bActive)
virtual void viewAdded(const UnoViewSharedPtr &rView) override
Notify new view.
bool eraseAllInkChanged(bool bEraseAllInk) override
virtual bool handleMousePressed(const awt::MouseEvent &e) override
virtual bool handleMouseReleased(const awt::MouseEvent &e) override
virtual void viewChanged(const UnoViewSharedPtr &) override
Notify changed view.
const PolyPolygonVector & getPolygons() const
bool colorChanged(RGBColor const &rUserColor) override
virtual void viewsChanged() override
Notify that all views changed.
virtual bool handleMouseMoved(const awt::MouseEvent &) override
bool widthChanged(double nUserStrokeWidth) override
virtual bool handleMouseDragged(const awt::MouseEvent &e) override
RGB color space class.
Definition: rgbcolor.hxx:35
::cppcanvas::IntSRGBA getIntegerColor() const
Create an integer sRGBA color.
Definition: color.cxx:299
void notifyUpdate()
Notify screen update.
virtual SlideBitmapSharedPtr getCurrentSlideBitmap(const UnoViewSharedPtr &rView) const =0
Request bitmap for current slide appearance.
Interface for handling user paint state changes.
PolyPolygonVector const & getPolygons() const
static UserPaintOverlaySharedPtr create(const RGBColor &rStrokeColor, double nStrokeWidth, const SlideShowContext &rContext, PolyPolygonVector &&rPolygons, bool bActive)
Create a UserPaintOverlay.
UserPaintOverlay(const UserPaintOverlay &)=delete
::std::shared_ptr< PaintOverlayHandler > mpHandler
Interface for handling view events.
#define TOOLS_WARN_EXCEPTION(area, stream)
HandlerSharedPtrT mpHandler
std::shared_ptr< PolyPolygon > PolyPolygonSharedPtr
std::shared_ptr< Canvas > CanvasSharedPtr
std::shared_ptr< T > make_shared(Args &&... args)
::std::shared_ptr< class UserPaintOverlay > UserPaintOverlaySharedPtr
::std::vector< ::cppcanvas::PolyPolygonSharedPtr > PolyPolygonVector
::std::shared_ptr< SlideBitmap > SlideBitmapSharedPtr
Definition: slidebitmap.hxx:76
std::vector< UnoViewSharedPtr > UnoViewVector
std::shared_ptr< UnoView > UnoViewSharedPtr
CursorManager & mrCursorManager
parent cursor manager
Definition: slideimpl.cxx:206
EventMultiplexer & mrEventMultiplexer
Definition: slideview.cxx:728
Common arguments for slideshow objects.
EventMultiplexer & mrMultiplexer