2 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
4 * This file is part of the LibreOffice project.
6 * This Source Code Form is subject to the terms of the Mozilla Public
7 * License, v. 2.0. If a copy of the MPL was not distributed with this
8 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 * This file incorporates work covered by the following license notice:
12 * Licensed to the Apache Software Foundation (ASF) under one or more
13 * contributor license agreements. See the NOTICE file distributed
14 * with this work for additional information regarding copyright
15 * ownership. The ASF licenses this file to you under the Apache
16 * License, Version 2.0 (the "License"); you may not use this file
17 * except in compliance with the License. You may obtain a copy of
18 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "PresenterSlideShowView.hxx"
22 #include "PresenterCanvasHelper.hxx"
23 #include "PresenterGeometryHelper.hxx"
24 #include "PresenterHelper.hxx"
25 #include "PresenterPaneContainer.hxx"
26 #include <DrawController.hxx>
27 #include <com/sun/star/awt/InvalidateStyle.hpp>
28 #include <com/sun/star/awt/PosSize.hpp>
29 #include <com/sun/star/awt/Pointer.hpp>
30 #include <com/sun/star/awt/Toolkit.hpp>
31 #include <com/sun/star/awt/WindowAttribute.hpp>
32 #include <com/sun/star/awt/XWindow.hpp>
33 #include <com/sun/star/awt/XWindowPeer.hpp>
34 #include <com/sun/star/drawing/XPresenterHelper.hpp>
35 #include <com/sun/star/drawing/framework/XConfigurationController.hpp>
36 #include <com/sun/star/rendering/CompositeOperation.hpp>
37 #include <com/sun/star/rendering/TextDirection.hpp>
38 #include <com/sun/star/rendering/TexturingMode.hpp>
39 #include <osl/mutex.hxx>
42 using namespace ::com::sun::star
;
43 using namespace ::com::sun::star::uno
;
44 using namespace ::com::sun::star::drawing::framework
;
46 namespace sdext::presenter
{
48 //===== PresenterSlideShowView ================================================
50 PresenterSlideShowView::PresenterSlideShowView (
51 css::uno::Reference
<css::uno::XComponentContext
> xContext
,
52 css::uno::Reference
<css::drawing::framework::XResourceId
> xViewId
,
53 const rtl::Reference
<::sd::DrawController
>& rxController
,
54 ::rtl::Reference
<PresenterController
> xPresenterController
)
55 : PresenterSlideShowViewInterfaceBase(m_aMutex
),
56 mxComponentContext(std::move(xContext
)),
57 mpPresenterController(std::move(xPresenterController
)),
58 mxViewId(std::move(xViewId
)),
59 mxController(rxController
),
60 mxSlideShowController(PresenterHelper::GetSlideShowController(rxController
)),
62 mnPageAspectRatio(28.0/21.0),
63 maBroadcaster(m_aMutex
),
64 mbIsForcedPaintPending(false),
65 mbIsPaintPending(true),
66 mbIsEndSlideVisible(false)
68 if (mpPresenterController
)
70 mnPageAspectRatio
= mpPresenterController
->GetSlideAspectRatio();
71 mpBackground
= mpPresenterController
->GetViewBackground(mxViewId
->getResourceURL());
75 void PresenterSlideShowView::LateInit()
77 mxSlideShow
.set( mxSlideShowController
->getSlideShow(), UNO_SET_THROW
);
78 Reference
<lang::XComponent
> xSlideShowComponent (mxSlideShow
, UNO_QUERY
);
79 xSlideShowComponent
->addEventListener(static_cast<awt::XWindowListener
*>(this));
81 Reference
<lang::XMultiComponentFactory
> xFactory (
82 mxComponentContext
->getServiceManager(), UNO_SET_THROW
);
83 mxPresenterHelper
.set (xFactory
->createInstanceWithContext(
84 "com.sun.star.comp.Draw.PresenterHelper",
88 // Use view id and controller to retrieve window and canvas from
89 // configuration controller.
90 Reference
<XConfigurationController
> xCC (mxController
->getConfigurationController());
94 mxTopPane
.set(xCC
->getResource(mxViewId
->getAnchor()->getAnchor()), UNO_QUERY
);
96 Reference
<XPane
> xPane (xCC
->getResource(mxViewId
->getAnchor()), UNO_QUERY_THROW
);
98 mxWindow
= xPane
->getWindow();
99 mxCanvas
= xPane
->getCanvas();
103 mxWindow
->addPaintListener(this);
104 mxWindow
->addWindowListener(this);
107 // The window does not have to paint a background. We do
109 Reference
<awt::XWindowPeer
> xPeer (mxWindow
, UNO_QUERY
);
111 xPeer
->setBackground(util::Color(0xff000000));
114 // Create a window for the actual slide show view. It is places
115 // centered and with maximal size inside the pane.
116 mxViewWindow
= CreateViewWindow(mxWindow
);
118 mxViewCanvas
= CreateViewCanvas(mxViewWindow
);
120 if (mxViewWindow
.is())
122 // Register listeners at window.
123 mxViewWindow
->addPaintListener(this);
124 mxViewWindow
->addMouseListener(this);
125 mxViewWindow
->addMouseMotionListener(this);
128 if (mxViewWindow
.is())
132 mxWindow
->setVisible(true);
134 // Add the new slide show view to the slide show.
135 if (mxSlideShow
.is() && ! mbIsViewAdded
)
137 impl_addAndConfigureView();
138 mbIsViewAdded
= true;
141 // Read text for one past last slide.
142 PresenterConfigurationAccess
aConfiguration (
144 PresenterConfigurationAccess::msPresenterScreenRootName
,
145 PresenterConfigurationAccess::READ_ONLY
);
146 aConfiguration
.GetConfigurationNode(
147 "Presenter/Views/CurrentSlidePreview/"
148 "Strings/ClickToExitPresentationText/String")
149 >>= msClickToExitPresentationText
;
150 aConfiguration
.GetConfigurationNode(
151 "Presenter/Views/CurrentSlidePreview/"
152 "Strings/ClickToExitPresentationTitle/String")
153 >>= msClickToExitPresentationTitle
;
156 PresenterSlideShowView::~PresenterSlideShowView()
160 void PresenterSlideShowView::disposing()
162 // Tell all listeners that we are disposed.
163 lang::EventObject aEvent
;
164 aEvent
.Source
= static_cast<XWeak
*>(this);
166 ::cppu::OInterfaceContainerHelper
* pIterator
167 = maBroadcaster
.getContainer(cppu::UnoType
<lang::XEventListener
>::get());
168 if (pIterator
!= nullptr)
169 pIterator
->disposeAndClear(aEvent
);
172 // XPaintListener, XModifyListener,XMouseListener,XMouseMotionListener,XWindowListener?
176 mxWindow
->removePaintListener(this);
177 mxWindow
->removeMouseListener(this);
178 mxWindow
->removeMouseMotionListener(this);
179 mxWindow
->removeWindowListener(this);
182 mxSlideShowController
= nullptr;
183 mxSlideShow
= nullptr;
184 if (mxViewCanvas
.is())
186 Reference
<XComponent
> xComponent (mxViewCanvas
, UNO_QUERY
);
187 mxViewCanvas
= nullptr;
189 xComponent
->dispose();
191 if (mxViewWindow
.is())
193 Reference
<XComponent
> xComponent
= mxViewWindow
;
194 mxViewWindow
= nullptr;
196 xComponent
->dispose();
200 Reference
<XComponent
> xComponent (mxPointer
, UNO_QUERY
);
203 xComponent
->dispose();
205 if (mxBackgroundPolygon1
.is())
207 Reference
<XComponent
> xComponent (mxBackgroundPolygon1
, UNO_QUERY
);
208 mxBackgroundPolygon1
= nullptr;
210 xComponent
->dispose();
212 if (mxBackgroundPolygon2
.is())
214 Reference
<XComponent
> xComponent (mxBackgroundPolygon2
, UNO_QUERY
);
215 mxBackgroundPolygon2
= nullptr;
217 xComponent
->dispose();
220 mxComponentContext
= nullptr;
221 mpPresenterController
= nullptr;
223 mxController
= nullptr;
225 mpBackground
.reset();
226 msClickToExitPresentationText
.clear();
227 msClickToExitPresentationTitle
.clear();
228 msTitleTemplate
.clear();
229 mxCurrentSlide
= nullptr;
232 //----- XDrawView -------------------------------------------------------------
234 void SAL_CALL
PresenterSlideShowView::setCurrentPage (
235 const css::uno::Reference
<css::drawing::XDrawPage
>& rxSlide
)
237 mxCurrentSlide
= rxSlide
;
238 if (mpPresenterController
239 && mxSlideShowController
.is()
240 && ! mpPresenterController
->GetCurrentSlide().is()
241 && ! mxSlideShowController
->isPaused())
243 mbIsEndSlideVisible
= true;
244 Reference
<awt::XWindowPeer
> xPeer (mxViewWindow
, UNO_QUERY
);
246 xPeer
->invalidate(awt::InvalidateStyle::NOTRANSPARENT
);
248 // For the end slide we use a special title, without the (n of m)
249 // part. Save the title template for the case that the user goes
251 PresenterPaneContainer::SharedPaneDescriptor
pDescriptor (
252 mpPresenterController
->GetPaneContainer()->FindViewURL(mxViewId
->getResourceURL()));
255 msTitleTemplate
= pDescriptor
->msTitleTemplate
;
256 pDescriptor
->msTitleTemplate
= msClickToExitPresentationTitle
;
257 mpPresenterController
->UpdatePaneTitles();
260 else if (mbIsEndSlideVisible
)
262 mbIsEndSlideVisible
= false;
264 // Restore the title template.
265 PresenterPaneContainer::SharedPaneDescriptor
pDescriptor (
266 mpPresenterController
->GetPaneContainer()->FindViewURL(mxViewId
->getResourceURL()));
269 pDescriptor
->msTitleTemplate
= msTitleTemplate
;
270 pDescriptor
->msTitle
.clear();
271 mpPresenterController
->UpdatePaneTitles();
276 css::uno::Reference
<css::drawing::XDrawPage
> SAL_CALL
PresenterSlideShowView::getCurrentPage()
278 return mxCurrentSlide
;
281 //----- CachablePresenterView -------------------------------------------------
283 void PresenterSlideShowView::ReleaseView()
285 if (mxSlideShow
.is() && mbIsViewAdded
)
287 mxSlideShow
->removeView(this);
288 mbIsViewAdded
= false;
292 //----- XSlideShowView --------------------------------------------------------
294 Reference
<rendering::XSpriteCanvas
> SAL_CALL
PresenterSlideShowView::getCanvas()
298 return Reference
<rendering::XSpriteCanvas
>(mxViewCanvas
, UNO_QUERY
);
301 void SAL_CALL
PresenterSlideShowView::clear()
304 mbIsForcedPaintPending
= false;
305 mbIsPaintPending
= false;
307 if (!(mxViewCanvas
.is() && mxViewWindow
.is()))
310 // Create a polygon for the window outline.
311 awt::Rectangle
aViewWindowBox (mxViewWindow
->getPosSize());
312 Reference
<rendering::XPolyPolygon2D
> xPolygon (PresenterGeometryHelper::CreatePolygon(
313 awt::Rectangle(0,0, aViewWindowBox
.Width
,aViewWindowBox
.Height
),
314 mxViewCanvas
->getDevice()));
316 rendering::ViewState
aViewState (
317 geometry::AffineMatrix2D(1,0,0, 0,1,0),
319 double const aColor
[4] = {0,0,0,0};
320 rendering::RenderState
aRenderState(
321 geometry::AffineMatrix2D(1,0,0, 0,1,0),
323 Sequence
<double>(aColor
,4),
324 rendering::CompositeOperation::SOURCE
);
325 mxViewCanvas
->fillPolyPolygon(xPolygon
, aViewState
, aRenderState
);
328 geometry::AffineMatrix2D SAL_CALL
PresenterSlideShowView::getTransformation()
332 if (mxViewWindow
.is())
334 // When the mbIsInModifyNotification is set then a slightly modified
335 // version of the transformation is returned in order to get past
336 // optimizations the avoid updates when the transformation is
337 // unchanged (when the window size changes then due to the constant
338 // aspect ratio the size of the preview may remain the same while
339 // the position changes. The position, however, is represented by
340 // the position of the view window. This transformation is given
341 // relative to the view window and therefore does not contain the
343 const awt::Rectangle aWindowBox
= mxViewWindow
->getPosSize();
344 return geometry::AffineMatrix2D(
345 aWindowBox
.Width
-1, 0, 0,
346 0, aWindowBox
.Height
-1, 0);
350 return geometry::AffineMatrix2D(1,0,0, 0,1,0);
354 geometry::IntegerSize2D SAL_CALL
PresenterSlideShowView::getTranslationOffset()
357 return geometry::IntegerSize2D(0,0);
360 void SAL_CALL
PresenterSlideShowView::addTransformationChangedListener(
361 const Reference
<util::XModifyListener
>& rxListener
)
364 maBroadcaster
.addListener(
365 cppu::UnoType
<util::XModifyListener
>::get(),
369 void SAL_CALL
PresenterSlideShowView::removeTransformationChangedListener(
370 const Reference
<util::XModifyListener
>& rxListener
)
373 maBroadcaster
.removeListener(
374 cppu::UnoType
<util::XModifyListener
>::get(),
378 void SAL_CALL
PresenterSlideShowView::addPaintListener(
379 const Reference
<awt::XPaintListener
>& rxListener
)
382 maBroadcaster
.addListener(
383 cppu::UnoType
<awt::XPaintListener
>::get(),
387 void SAL_CALL
PresenterSlideShowView::removePaintListener(
388 const Reference
<awt::XPaintListener
>& rxListener
)
391 maBroadcaster
.removeListener(
392 cppu::UnoType
<awt::XPaintListener
>::get(),
396 void SAL_CALL
PresenterSlideShowView::addMouseListener(
397 const Reference
<awt::XMouseListener
>& rxListener
)
400 maBroadcaster
.addListener(
401 cppu::UnoType
<awt::XMouseListener
>::get(),
405 void SAL_CALL
PresenterSlideShowView::removeMouseListener(
406 const Reference
<awt::XMouseListener
>& rxListener
)
409 maBroadcaster
.removeListener(
410 cppu::UnoType
<awt::XMouseListener
>::get(),
414 void SAL_CALL
PresenterSlideShowView::addMouseMotionListener(
415 const Reference
<awt::XMouseMotionListener
>& rxListener
)
418 maBroadcaster
.addListener(
419 cppu::UnoType
<awt::XMouseMotionListener
>::get(),
423 void SAL_CALL
PresenterSlideShowView::removeMouseMotionListener(
424 const Reference
<awt::XMouseMotionListener
>& rxListener
)
427 maBroadcaster
.removeListener(
428 cppu::UnoType
<awt::XMouseMotionListener
>::get(),
432 void SAL_CALL
PresenterSlideShowView::setMouseCursor(::sal_Int16 nPointerShape
)
436 // Create a pointer when it does not yet exist.
437 if ( ! mxPointer
.is())
439 mxPointer
= awt::Pointer::create(mxComponentContext
);
442 // Set the pointer to the given shape and the window(peer) to the
444 Reference
<awt::XWindowPeer
> xPeer (mxViewWindow
, UNO_QUERY
);
445 if (mxPointer
.is() && xPeer
.is())
447 mxPointer
->setType(nPointerShape
);
448 xPeer
->setPointer(mxPointer
);
452 awt::Rectangle SAL_CALL
PresenterSlideShowView::getCanvasArea( )
454 if( mxViewWindow
.is() && mxTopPane
.is() )
455 return mxPresenterHelper
->getWindowExtentsRelative( mxViewWindow
, mxTopPane
->getWindow() );
457 awt::Rectangle aRectangle
;
459 aRectangle
.X
= aRectangle
.Y
= aRectangle
.Width
= aRectangle
.Height
= 0;
464 //----- lang::XEventListener --------------------------------------------------
466 void SAL_CALL
PresenterSlideShowView::disposing (const lang::EventObject
& rEvent
)
468 if (rEvent
.Source
== mxViewWindow
)
469 mxViewWindow
= nullptr;
470 else if (rEvent
.Source
== mxSlideShow
)
471 mxSlideShow
= nullptr;
474 //----- XPaintListener --------------------------------------------------------
476 void SAL_CALL
PresenterSlideShowView::windowPaint (const awt::PaintEvent
& rEvent
)
478 // Deactivated views must not be painted.
479 if ( ! mbIsPresenterViewActive
)
482 awt::Rectangle
aViewWindowBox (mxViewWindow
->getPosSize());
483 if (aViewWindowBox
.Width
<= 0 || aViewWindowBox
.Height
<= 0)
486 if (rEvent
.Source
== mxWindow
)
487 PaintOuterWindow(rEvent
.UpdateRect
);
488 else if (mbIsEndSlideVisible
)
489 PaintEndSlide(rEvent
.UpdateRect
);
491 PaintInnerWindow(rEvent
);
494 //----- XMouseListener --------------------------------------------------------
496 void SAL_CALL
PresenterSlideShowView::mousePressed (const awt::MouseEvent
& rEvent
)
498 awt::MouseEvent
aEvent (rEvent
);
499 aEvent
.Source
= static_cast<XWeak
*>(this);
500 ::cppu::OInterfaceContainerHelper
* pIterator
501 = maBroadcaster
.getContainer(cppu::UnoType
<awt::XMouseListener
>::get());
502 if (pIterator
!= nullptr)
504 pIterator
->notifyEach(&awt::XMouseListener::mousePressed
, aEvent
);
507 // Only when the end slide is displayed we forward the mouse event to
508 // the PresenterController so that it switches to the next slide and
509 // ends the presentation.
510 if (mbIsEndSlideVisible
)
511 if (mpPresenterController
)
512 mpPresenterController
->HandleMouseClick(rEvent
);
515 void SAL_CALL
PresenterSlideShowView::mouseReleased (const awt::MouseEvent
& rEvent
)
517 awt::MouseEvent
aEvent (rEvent
);
518 aEvent
.Source
= static_cast<XWeak
*>(this);
519 ::cppu::OInterfaceContainerHelper
* pIterator
520 = maBroadcaster
.getContainer(cppu::UnoType
<awt::XMouseListener
>::get());
521 if (pIterator
!= nullptr)
523 pIterator
->notifyEach(&awt::XMouseListener::mouseReleased
, aEvent
);
527 void SAL_CALL
PresenterSlideShowView::mouseEntered (const awt::MouseEvent
& rEvent
)
529 awt::MouseEvent
aEvent (rEvent
);
530 aEvent
.Source
= static_cast<XWeak
*>(this);
531 ::cppu::OInterfaceContainerHelper
* pIterator
532 = maBroadcaster
.getContainer(cppu::UnoType
<awt::XMouseListener
>::get());
533 if (pIterator
!= nullptr)
535 pIterator
->notifyEach(&awt::XMouseListener::mouseEntered
, aEvent
);
539 void SAL_CALL
PresenterSlideShowView::mouseExited (const awt::MouseEvent
& rEvent
)
541 awt::MouseEvent
aEvent (rEvent
);
542 aEvent
.Source
= static_cast<XWeak
*>(this);
543 ::cppu::OInterfaceContainerHelper
* pIterator
544 = maBroadcaster
.getContainer(cppu::UnoType
<awt::XMouseListener
>::get());
545 if (pIterator
!= nullptr)
547 pIterator
->notifyEach(&awt::XMouseListener::mouseExited
, aEvent
);
551 //----- XMouseMotionListener --------------------------------------------------
553 void SAL_CALL
PresenterSlideShowView::mouseDragged (const awt::MouseEvent
& rEvent
)
555 awt::MouseEvent
aEvent (rEvent
);
556 aEvent
.Source
= static_cast<XWeak
*>(this);
557 ::cppu::OInterfaceContainerHelper
* pIterator
558 = maBroadcaster
.getContainer(cppu::UnoType
<awt::XMouseMotionListener
>::get());
559 if (pIterator
!= nullptr)
561 pIterator
->notifyEach(&awt::XMouseMotionListener::mouseDragged
, aEvent
);
565 void SAL_CALL
PresenterSlideShowView::mouseMoved (const awt::MouseEvent
& rEvent
)
567 awt::MouseEvent
aEvent (rEvent
);
568 aEvent
.Source
= static_cast<XWeak
*>(this);
569 ::cppu::OInterfaceContainerHelper
* pIterator
570 = maBroadcaster
.getContainer(cppu::UnoType
<awt::XMouseMotionListener
>::get());
571 if (pIterator
!= nullptr)
573 pIterator
->notifyEach(&awt::XMouseMotionListener::mouseMoved
, aEvent
);
577 //----- XWindowListener -------------------------------------------------------
579 void SAL_CALL
PresenterSlideShowView::windowResized (const awt::WindowEvent
&)
582 ::osl::MutexGuard
aGuard (::osl::Mutex::getGlobalMutex());
587 void SAL_CALL
PresenterSlideShowView::windowMoved (const awt::WindowEvent
&)
589 if ( ! mbIsPaintPending
)
590 mbIsForcedPaintPending
= true;
593 void SAL_CALL
PresenterSlideShowView::windowShown (const lang::EventObject
&)
598 void SAL_CALL
PresenterSlideShowView::windowHidden (const lang::EventObject
&) {}
600 //----- XView -----------------------------------------------------------------
602 Reference
<XResourceId
> SAL_CALL
PresenterSlideShowView::getResourceId()
607 sal_Bool SAL_CALL
PresenterSlideShowView::isAnchorOnly()
612 //----- CachablePresenterView -------------------------------------------------
614 void PresenterSlideShowView::ActivatePresenterView()
616 if (mxSlideShow
.is() && ! mbIsViewAdded
)
618 impl_addAndConfigureView();
619 mbIsViewAdded
= true;
623 void PresenterSlideShowView::DeactivatePresenterView()
625 if (mxSlideShow
.is() && mbIsViewAdded
)
627 mxSlideShow
->removeView(this);
628 mbIsViewAdded
= false;
633 void PresenterSlideShowView::PaintOuterWindow (const awt::Rectangle
& rRepaintBox
)
635 if ( ! mxCanvas
.is())
641 const rendering::ViewState
aViewState(
642 geometry::AffineMatrix2D(1,0,0, 0,1,0),
643 PresenterGeometryHelper::CreatePolygon(rRepaintBox
, mxCanvas
->getDevice()));
645 rendering::RenderState
aRenderState (
646 geometry::AffineMatrix2D(1,0,0, 0,1,0),
649 rendering::CompositeOperation::SOURCE
);
651 Reference
<rendering::XBitmap
> xBackgroundBitmap (mpBackground
->GetNormalBitmap());
652 if (xBackgroundBitmap
.is())
654 const geometry::IntegerSize2D
aBitmapSize(xBackgroundBitmap
->getSize());
655 Sequence
<rendering::Texture
> aTextures
658 geometry::AffineMatrix2D( aBitmapSize
.Width
,0,0, 0,aBitmapSize
.Height
,0),
664 rendering::StrokeAttributes(),
665 rendering::TexturingMode::REPEAT
,
666 rendering::TexturingMode::REPEAT
670 if (mxBackgroundPolygon1
.is())
671 mxCanvas
->fillTexturedPolyPolygon(
672 mxBackgroundPolygon1
,
676 if (mxBackgroundPolygon2
.is())
677 mxCanvas
->fillTexturedPolyPolygon(
678 mxBackgroundPolygon2
,
685 PresenterCanvasHelper::SetDeviceColor(aRenderState
, mpBackground
->maReplacementColor
);
687 if (mxBackgroundPolygon1
.is())
688 mxCanvas
->fillPolyPolygon(mxBackgroundPolygon1
, aViewState
, aRenderState
);
689 if (mxBackgroundPolygon2
.is())
690 mxCanvas
->fillPolyPolygon(mxBackgroundPolygon2
, aViewState
, aRenderState
);
694 void PresenterSlideShowView::PaintEndSlide (const awt::Rectangle
& rRepaintBox
)
696 if ( ! mxCanvas
.is())
699 const rendering::ViewState
aViewState(
700 geometry::AffineMatrix2D(1,0,0, 0,1,0),
701 PresenterGeometryHelper::CreatePolygon(rRepaintBox
, mxCanvas
->getDevice()));
703 rendering::RenderState
aRenderState (
704 geometry::AffineMatrix2D(1,0,0, 0,1,0),
707 rendering::CompositeOperation::SOURCE
);
708 PresenterCanvasHelper::SetDeviceColor(aRenderState
, util::Color(0x00000000));
709 mxCanvas
->fillPolyPolygon(
710 PresenterGeometryHelper::CreatePolygon(mxViewWindow
->getPosSize(), mxCanvas
->getDevice()),
716 if (!mpPresenterController
)
718 std::shared_ptr
<PresenterTheme
> pTheme (mpPresenterController
->GetTheme());
719 if (pTheme
== nullptr)
722 const OUString
sViewStyle (pTheme
->GetStyleName(mxViewId
->getResourceURL()));
723 PresenterTheme::SharedFontDescriptor
pFont (pTheme
->GetFont(sViewStyle
));
727 /// this is responsible of the " presentation exit " text inside the slide windows
728 PresenterCanvasHelper::SetDeviceColor(aRenderState
, util::Color(0x00ffffff));
729 aRenderState
.AffineTransform
.m02
= 20;
730 aRenderState
.AffineTransform
.m12
= 40;
731 const rendering::StringContext
aContext (
732 msClickToExitPresentationText
, 0, msClickToExitPresentationText
.getLength());
733 pFont
->PrepareFont(mxCanvas
);
734 const Reference
<rendering::XTextLayout
> xLayout (
735 pFont
->mxFont
->createTextLayout(aContext
,rendering::TextDirection::WEAK_LEFT_TO_RIGHT
,0));
736 mxCanvas
->drawTextLayout(
743 // Finally, in double buffered environments, request the changes to be
745 Reference
<rendering::XSpriteCanvas
> xSpriteCanvas (mxCanvas
, UNO_QUERY
);
746 if (xSpriteCanvas
.is())
747 xSpriteCanvas
->updateScreen(true);
750 void PresenterSlideShowView::PaintInnerWindow (const awt::PaintEvent
& rEvent
)
752 // Forward window paint to listeners.
753 awt::PaintEvent
aEvent (rEvent
);
754 aEvent
.Source
= static_cast<XWeak
*>(this);
755 ::cppu::OInterfaceContainerHelper
* pIterator
756 = maBroadcaster
.getContainer(cppu::UnoType
<awt::XPaintListener
>::get());
757 if (pIterator
!= nullptr)
759 pIterator
->notifyEach(&awt::XPaintListener::windowPaint
, aEvent
);
762 /** The slide show relies on the back buffer of the canvas not being
763 modified. With a shared canvas there are times when that can not be
766 if (mbIsForcedPaintPending
&& mxSlideShow
.is() && mbIsViewAdded
)
768 mxSlideShow
->removeView(this);
769 impl_addAndConfigureView();
772 // Finally, in double buffered environments, request the changes to be
774 Reference
<rendering::XSpriteCanvas
> xSpriteCanvas (mxCanvas
, UNO_QUERY
);
775 if (xSpriteCanvas
.is())
776 xSpriteCanvas
->updateScreen(true);
779 Reference
<awt::XWindow
> PresenterSlideShowView::CreateViewWindow (
780 const Reference
<awt::XWindow
>& rxParentWindow
) const
782 Reference
<awt::XWindow
> xViewWindow
;
785 Reference
<lang::XMultiComponentFactory
> xFactory (mxComponentContext
->getServiceManager());
786 if ( ! xFactory
.is())
789 Reference
<awt::XToolkit2
> xToolkit
= awt::Toolkit::create(mxComponentContext
);
790 awt::WindowDescriptor
aWindowDescriptor (
791 awt::WindowClass_CONTAINER
,
793 Reference
<awt::XWindowPeer
>(rxParentWindow
,UNO_QUERY_THROW
),
794 -1, // parent index not available
795 awt::Rectangle(0,0,10,10),
796 awt::WindowAttribute::SIZEABLE
797 | awt::WindowAttribute::MOVEABLE
798 | awt::WindowAttribute::NODECORATION
);
799 xViewWindow
.set( xToolkit
->createWindow(aWindowDescriptor
),UNO_QUERY_THROW
);
801 // Make the background transparent. The slide show paints its own background.
802 Reference
<awt::XWindowPeer
> xPeer (xViewWindow
, UNO_QUERY_THROW
);
803 xPeer
->setBackground(0xff000000);
805 xViewWindow
->setVisible(true);
807 catch (RuntimeException
&)
813 Reference
<rendering::XCanvas
> PresenterSlideShowView::CreateViewCanvas (
814 const Reference
<awt::XWindow
>& rxViewWindow
) const
816 // Create a canvas for the view window.
817 return mxPresenterHelper
->createSharedCanvas(
818 Reference
<rendering::XSpriteCanvas
>(mxTopPane
->getCanvas(), UNO_QUERY
),
819 mxTopPane
->getWindow(),
820 mxTopPane
->getCanvas(),
821 mxTopPane
->getWindow(),
825 void PresenterSlideShowView::Resize()
827 if ( ! mxWindow
.is() || ! mxViewWindow
.is())
830 const awt::Rectangle
aWindowBox (mxWindow
->getPosSize());
831 if (aWindowBox
.Height
> 0)
833 awt::Rectangle aViewWindowBox
;
834 const double nWindowAspectRatio (
835 double(aWindowBox
.Width
) / double(aWindowBox
.Height
));
836 if (nWindowAspectRatio
> mnPageAspectRatio
)
838 // Slides will be painted with the full parent window height.
839 aViewWindowBox
.Width
= sal_Int32(aWindowBox
.Height
* mnPageAspectRatio
+ 0.5);
840 aViewWindowBox
.Height
= aWindowBox
.Height
;
841 aViewWindowBox
.X
= (aWindowBox
.Width
- aViewWindowBox
.Width
) / 2;
842 aViewWindowBox
.Y
= 0;
846 // Slides will be painted with the full parent window width.
847 aViewWindowBox
.Width
= aWindowBox
.Width
;
848 aViewWindowBox
.Height
= sal_Int32(aWindowBox
.Width
/ mnPageAspectRatio
+ 0.5);
849 aViewWindowBox
.X
= 0;
850 aViewWindowBox
.Y
= (aWindowBox
.Height
- aViewWindowBox
.Height
) / 2;
852 mxViewWindow
->setPosSize(
855 aViewWindowBox
.Width
,
856 aViewWindowBox
.Height
,
857 awt::PosSize::POSSIZE
);
860 // Clear the background polygon so that on the next paint it is created
862 CreateBackgroundPolygons();
864 // Notify listeners that the transformation that maps the view into the
865 // window has changed.
866 lang::EventObject
aEvent (static_cast<XWeak
*>(this));
867 ::cppu::OInterfaceContainerHelper
* pIterator
868 = maBroadcaster
.getContainer(cppu::UnoType
<util::XModifyListener
>::get());
869 if (pIterator
!= nullptr)
871 pIterator
->notifyEach(&util::XModifyListener::modified
, aEvent
);
874 // Due to constant aspect ratio resizing may lead a preview that changes
875 // its position but not its size. This invalidates the back buffer and
876 // we have to enforce a complete repaint.
877 if ( ! mbIsPaintPending
)
878 mbIsForcedPaintPending
= true;
881 void PresenterSlideShowView::CreateBackgroundPolygons()
883 const awt::Rectangle
aWindowBox (mxWindow
->getPosSize());
884 const awt::Rectangle
aViewWindowBox (mxViewWindow
->getPosSize());
885 if (aWindowBox
.Height
== aViewWindowBox
.Height
&& aWindowBox
.Width
== aViewWindowBox
.Width
)
887 mxBackgroundPolygon1
= nullptr;
888 mxBackgroundPolygon2
= nullptr;
890 else if (aWindowBox
.Height
== aViewWindowBox
.Height
)
892 // Paint two boxes to the left and right of the view window.
893 mxBackgroundPolygon1
= PresenterGeometryHelper::CreatePolygon(
899 mxCanvas
->getDevice());
900 mxBackgroundPolygon2
= PresenterGeometryHelper::CreatePolygon(
902 aViewWindowBox
.X
+ aViewWindowBox
.Width
,
904 aWindowBox
.Width
- aViewWindowBox
.X
- aViewWindowBox
.Width
,
906 mxCanvas
->getDevice());
910 // Paint two boxes above and below the view window.
911 mxBackgroundPolygon1
= PresenterGeometryHelper::CreatePolygon(
917 mxCanvas
->getDevice());
918 mxBackgroundPolygon2
= PresenterGeometryHelper::CreatePolygon(
921 aViewWindowBox
.Y
+ aViewWindowBox
.Height
,
923 aWindowBox
.Height
- aViewWindowBox
.Y
- aViewWindowBox
.Height
),
924 mxCanvas
->getDevice());
928 void PresenterSlideShowView::ThrowIfDisposed()
930 if (rBHelper
.bDisposed
|| rBHelper
.bInDispose
)
932 throw lang::DisposedException (
933 "PresenterSlideShowView object has already been disposed",
934 static_cast<uno::XWeak
*>(this));
938 void PresenterSlideShowView::impl_addAndConfigureView()
940 Reference
<presentation::XSlideShowView
> xView (this);
941 mxSlideShow
->addView(xView
);
942 // Prevent embedded sounds being played twice at the same time by
943 // disabling sound for the new slide show view.
944 beans::PropertyValue aProperty
;
945 aProperty
.Name
= "IsSoundEnabled";
946 Sequence
<Any
> aValues
{ Any(xView
), Any(false) };
947 aProperty
.Value
<<= aValues
;
948 mxSlideShow
->setProperty(aProperty
);
951 } // end of namespace ::sd::presenter
953 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */