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 "vcl/svapp.hxx"
23 #include "PresenterCanvasHelper.hxx"
24 #include "PresenterGeometryHelper.hxx"
25 #include "PresenterHelper.hxx"
26 #include "PresenterPaneContainer.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/XWindow2.hpp>
34 #include <com/sun/star/awt/XWindowPeer.hpp>
35 #include <com/sun/star/beans/XPropertySet.hpp>
36 #include <com/sun/star/drawing/CanvasFeature.hpp>
37 #include <com/sun/star/drawing/XPresenterHelper.hpp>
38 #include <com/sun/star/drawing/framework/XControllerManager.hpp>
39 #include <com/sun/star/drawing/framework/XConfigurationController.hpp>
40 #include <com/sun/star/rendering/CompositeOperation.hpp>
41 #include <com/sun/star/rendering/TextDirection.hpp>
42 #include <com/sun/star/rendering/TexturingMode.hpp>
43 #include <osl/mutex.hxx>
45 using namespace ::com::sun::star
;
46 using namespace ::com::sun::star::uno
;
47 using namespace ::com::sun::star::drawing::framework
;
49 namespace sdext
{ namespace presenter
{
51 //===== PresenterSlideShowView ================================================
53 PresenterSlideShowView::PresenterSlideShowView (
54 const css::uno::Reference
<css::uno::XComponentContext
>& rxContext
,
55 const css::uno::Reference
<css::drawing::framework::XResourceId
>& rxViewId
,
56 const css::uno::Reference
<css::frame::XController
>& rxController
,
57 const ::rtl::Reference
<PresenterController
>& rpPresenterController
)
58 : PresenterSlideShowViewInterfaceBase(m_aMutex
),
59 mxComponentContext(rxContext
),
60 mpPresenterController(rpPresenterController
),
62 mxController(rxController
),
63 mxSlideShowController(PresenterHelper::GetSlideShowController(rxController
)),
72 mxBackgroundPolygon1(),
73 mxBackgroundPolygon2(),
75 mnPageAspectRatio(28.0/21.0),
76 maBroadcaster(m_aMutex
),
78 mbIsInModifyNotification(false),
79 mbIsForcedPaintPending(false),
80 mbIsPaintPending(true),
81 msClickToExitPresentationText(),
82 msClickToExitPresentationTitle(),
84 mbIsEndSlideVisible(false),
87 if (mpPresenterController
.get() != NULL
)
89 mnPageAspectRatio
= mpPresenterController
->GetSlideAspectRatio();
90 mpBackground
= mpPresenterController
->GetViewBackground(mxViewId
->getResourceURL());
94 void PresenterSlideShowView::LateInit()
96 mxSlideShow
= Reference
<presentation::XSlideShow
> (
97 mxSlideShowController
->getSlideShow(), UNO_QUERY_THROW
);
98 Reference
<lang::XComponent
> xSlideShowComponent (mxSlideShow
, UNO_QUERY
);
99 if (xSlideShowComponent
.is())
100 xSlideShowComponent
->addEventListener(static_cast<awt::XWindowListener
*>(this));
102 Reference
<lang::XMultiComponentFactory
> xFactory (
103 mxComponentContext
->getServiceManager(), UNO_QUERY_THROW
);
104 mxPresenterHelper
.set (xFactory
->createInstanceWithContext(
105 OUString("com.sun.star.comp.Draw.PresenterHelper"),
109 // Use view id and controller to retrieve window and canvas from
110 // configuration controller.
111 Reference
<XControllerManager
> xCM (mxController
, UNO_QUERY_THROW
);
112 Reference
<XConfigurationController
> xCC (xCM
->getConfigurationController());
116 mxTopPane
.set(xCC
->getResource(mxViewId
->getAnchor()->getAnchor()), UNO_QUERY
);
118 Reference
<XPane
> xPane (xCC
->getResource(mxViewId
->getAnchor()), UNO_QUERY_THROW
);
120 mxWindow
= xPane
->getWindow();
121 mxCanvas
= xPane
->getCanvas();
125 mxWindow
->addPaintListener(this);
126 mxWindow
->addWindowListener(this);
129 // The window does not have to paint a background. We do
131 Reference
<awt::XWindowPeer
> xPeer (mxWindow
, UNO_QUERY
);
133 xPeer
->setBackground(util::Color(0xff000000));
136 // Create a window for the actual slide show view. It is places
137 // centered and with maximal size inside the pane.
138 mxViewWindow
= CreateViewWindow(mxWindow
);
140 mxViewCanvas
= CreateViewCanvas(mxViewWindow
);
142 if (mxViewWindow
.is())
144 // Register listeners at window.
145 mxViewWindow
->addPaintListener(this);
146 mxViewWindow
->addMouseListener(this);
147 mxViewWindow
->addMouseMotionListener(this);
150 if (mxViewWindow
.is())
154 mxWindow
->setVisible(sal_True
);
156 // Add the new slide show view to the slide show.
157 if (mxSlideShow
.is() && ! mbIsViewAdded
)
159 impl_addAndConfigureView();
160 mbIsViewAdded
= true;
163 // Read text for one past last slide.
164 PresenterConfigurationAccess
aConfiguration (
166 PresenterConfigurationAccess::msPresenterScreenRootName
,
167 PresenterConfigurationAccess::READ_ONLY
);
168 aConfiguration
.GetConfigurationNode(
169 "Presenter/Views/CurrentSlidePreview/"
170 "Strings/ClickToExitPresentationText/String")
171 >>= msClickToExitPresentationText
;
172 aConfiguration
.GetConfigurationNode(
173 "Presenter/Views/CurrentSlidePreview/"
174 "Strings/ClickToExitPresentationTitle/String")
175 >>= msClickToExitPresentationTitle
;
178 PresenterSlideShowView::~PresenterSlideShowView()
182 void PresenterSlideShowView::disposing()
184 // Tell all listeners that we are disposed.
185 lang::EventObject aEvent
;
186 aEvent
.Source
= static_cast<XWeak
*>(this);
188 ::cppu::OInterfaceContainerHelper
* pIterator
189 = maBroadcaster
.getContainer(cppu::UnoType
<lang::XEventListener
>::get());
190 if (pIterator
!= NULL
)
191 pIterator
->disposeAndClear(aEvent
);
194 // XPaintListener, XModifyListener,XMouseListener,XMouseMotionListener,XWindowListener?
198 mxWindow
->removePaintListener(this);
199 mxWindow
->removeMouseListener(this);
200 mxWindow
->removeMouseMotionListener(this);
201 mxWindow
->removeWindowListener(this);
204 mxSlideShowController
= NULL
;
206 if (mxViewCanvas
.is())
208 Reference
<XComponent
> xComponent (mxViewCanvas
, UNO_QUERY
);
211 xComponent
->dispose();
213 if (mxViewWindow
.is())
215 Reference
<XComponent
> xComponent (mxViewWindow
, UNO_QUERY
);
218 xComponent
->dispose();
222 Reference
<XComponent
> xComponent (mxPointer
, UNO_QUERY
);
225 xComponent
->dispose();
227 if (mxBackgroundPolygon1
.is())
229 Reference
<XComponent
> xComponent (mxBackgroundPolygon1
, UNO_QUERY
);
230 mxBackgroundPolygon1
= NULL
;
232 xComponent
->dispose();
234 if (mxBackgroundPolygon2
.is())
236 Reference
<XComponent
> xComponent (mxBackgroundPolygon2
, UNO_QUERY
);
237 mxBackgroundPolygon2
= NULL
;
239 xComponent
->dispose();
242 mxComponentContext
= NULL
;
243 mpPresenterController
= NULL
;
247 mpBackground
.reset();
248 msClickToExitPresentationText
.clear();
249 msClickToExitPresentationTitle
.clear();
250 msTitleTemplate
.clear();
251 mxCurrentSlide
= NULL
;
254 //----- XDrawView -------------------------------------------------------------
256 void SAL_CALL
PresenterSlideShowView::setCurrentPage (
257 const css::uno::Reference
<css::drawing::XDrawPage
>& rxSlide
)
258 throw (css::uno::RuntimeException
, std::exception
)
260 mxCurrentSlide
= rxSlide
;
261 if (mpPresenterController
.get() != NULL
262 && mxSlideShowController
.is()
263 && ! mpPresenterController
->GetCurrentSlide().is()
264 && ! mxSlideShowController
->isPaused())
266 mbIsEndSlideVisible
= true;
267 Reference
<awt::XWindowPeer
> xPeer (mxViewWindow
, UNO_QUERY
);
269 xPeer
->invalidate(awt::InvalidateStyle::NOTRANSPARENT
);
271 // For the end slide we use a special title, without the (n of m)
272 // part. Save the title template for the case that the user goes
274 PresenterPaneContainer::SharedPaneDescriptor
pDescriptor (
275 mpPresenterController
->GetPaneContainer()->FindViewURL(mxViewId
->getResourceURL()));
276 if (pDescriptor
.get() != NULL
)
278 msTitleTemplate
= pDescriptor
->msTitleTemplate
;
279 pDescriptor
->msTitleTemplate
= msClickToExitPresentationTitle
;
280 mpPresenterController
->UpdatePaneTitles();
283 else if (mbIsEndSlideVisible
)
285 mbIsEndSlideVisible
= false;
287 // Restore the title template.
288 PresenterPaneContainer::SharedPaneDescriptor
pDescriptor (
289 mpPresenterController
->GetPaneContainer()->FindViewURL(mxViewId
->getResourceURL()));
290 if (pDescriptor
.get() != NULL
)
292 pDescriptor
->msTitleTemplate
= msTitleTemplate
;
293 (pDescriptor
->msTitle
).clear();
294 mpPresenterController
->UpdatePaneTitles();
299 css::uno::Reference
<css::drawing::XDrawPage
> SAL_CALL
PresenterSlideShowView::getCurrentPage()
300 throw (css::uno::RuntimeException
, std::exception
)
302 return mxCurrentSlide
;
305 //----- CachablePresenterView -------------------------------------------------
307 void PresenterSlideShowView::ReleaseView()
309 if (mxSlideShow
.is() && mbIsViewAdded
)
311 mxSlideShow
->removeView(this);
312 mbIsViewAdded
= false;
316 //----- XSlideShowView --------------------------------------------------------
318 Reference
<rendering::XSpriteCanvas
> SAL_CALL
PresenterSlideShowView::getCanvas()
319 throw (RuntimeException
, std::exception
)
323 return Reference
<rendering::XSpriteCanvas
>(mxViewCanvas
, UNO_QUERY
);
326 void SAL_CALL
PresenterSlideShowView::clear()
327 throw (RuntimeException
, std::exception
)
330 mbIsForcedPaintPending
= false;
331 mbIsPaintPending
= false;
333 if (mxViewCanvas
.is() && mxViewWindow
.is())
335 // Create a polygon for the window outline.
336 awt::Rectangle
aViewWindowBox (mxViewWindow
->getPosSize());
337 Reference
<rendering::XPolyPolygon2D
> xPolygon (PresenterGeometryHelper::CreatePolygon(
338 awt::Rectangle(0,0, aViewWindowBox
.Width
,aViewWindowBox
.Height
),
339 mxViewCanvas
->getDevice()));
341 rendering::ViewState
aViewState (
342 geometry::AffineMatrix2D(1,0,0, 0,1,0),
344 double aColor
[4] = {0,0,0,0};
345 rendering::RenderState
aRenderState(
346 geometry::AffineMatrix2D(1,0,0, 0,1,0),
348 Sequence
<double>(aColor
,4),
349 rendering::CompositeOperation::SOURCE
);
350 mxViewCanvas
->fillPolyPolygon(xPolygon
, aViewState
, aRenderState
);
354 geometry::AffineMatrix2D SAL_CALL
PresenterSlideShowView::getTransformation()
355 throw (RuntimeException
, std::exception
)
359 if (mxViewWindow
.is())
361 // When the mbIsInModifyNotification is set then a slightly modified
362 // version of the transformation is returned in order to get past
363 // optimizations the avoid updates when the transformation is
364 // unchanged (when the window size changes then due to the constant
365 // aspect ratio the size of the preview may remain the same while
366 // the position changes. The position, however, is repesented by
367 // the position of the view window. This transformation is given
368 // relative to the view window and therefore does not contain the
370 const awt::Rectangle aWindowBox
= mxViewWindow
->getPosSize();
371 return geometry::AffineMatrix2D(
372 aWindowBox
.Width
-1, 0, (mbIsInModifyNotification
? 1 : 0),
373 0, aWindowBox
.Height
-1, 0);
377 return geometry::AffineMatrix2D(1,0,0, 0,1,0);
381 geometry::IntegerSize2D SAL_CALL
PresenterSlideShowView::getTranslationOffset()
382 throw (RuntimeException
, std::exception
)
385 return geometry::IntegerSize2D(0,0);
388 void SAL_CALL
PresenterSlideShowView::addTransformationChangedListener(
389 const Reference
<util::XModifyListener
>& rxListener
)
390 throw (RuntimeException
, std::exception
)
393 maBroadcaster
.addListener(
394 cppu::UnoType
<util::XModifyListener
>::get(),
398 void SAL_CALL
PresenterSlideShowView::removeTransformationChangedListener(
399 const Reference
<util::XModifyListener
>& rxListener
)
400 throw (RuntimeException
, std::exception
)
403 maBroadcaster
.removeListener(
404 cppu::UnoType
<util::XModifyListener
>::get(),
408 void SAL_CALL
PresenterSlideShowView::addPaintListener(
409 const Reference
<awt::XPaintListener
>& rxListener
)
410 throw (RuntimeException
, std::exception
)
413 maBroadcaster
.addListener(
414 cppu::UnoType
<awt::XPaintListener
>::get(),
418 void SAL_CALL
PresenterSlideShowView::removePaintListener(
419 const Reference
<awt::XPaintListener
>& rxListener
)
420 throw (RuntimeException
, std::exception
)
423 maBroadcaster
.removeListener(
424 cppu::UnoType
<awt::XPaintListener
>::get(),
428 void SAL_CALL
PresenterSlideShowView::addMouseListener(
429 const Reference
<awt::XMouseListener
>& rxListener
)
430 throw (RuntimeException
, std::exception
)
433 maBroadcaster
.addListener(
434 cppu::UnoType
<awt::XMouseListener
>::get(),
438 void SAL_CALL
PresenterSlideShowView::removeMouseListener(
439 const Reference
<awt::XMouseListener
>& rxListener
)
440 throw (RuntimeException
, std::exception
)
443 maBroadcaster
.removeListener(
444 cppu::UnoType
<awt::XMouseListener
>::get(),
448 void SAL_CALL
PresenterSlideShowView::addMouseMotionListener(
449 const Reference
<awt::XMouseMotionListener
>& rxListener
)
450 throw (RuntimeException
, std::exception
)
453 maBroadcaster
.addListener(
454 cppu::UnoType
<awt::XMouseMotionListener
>::get(),
458 void SAL_CALL
PresenterSlideShowView::removeMouseMotionListener(
459 const Reference
<awt::XMouseMotionListener
>& rxListener
)
460 throw (RuntimeException
, std::exception
)
463 maBroadcaster
.removeListener(
464 cppu::UnoType
<awt::XMouseMotionListener
>::get(),
468 void SAL_CALL
PresenterSlideShowView::setMouseCursor(::sal_Int16 nPointerShape
)
469 throw (RuntimeException
, std::exception
)
473 // Create a pointer when it does not yet exist.
474 if ( ! mxPointer
.is())
476 mxPointer
= awt::Pointer::create(mxComponentContext
);
479 // Set the pointer to the given shape and the window(peer) to the
481 Reference
<awt::XWindowPeer
> xPeer (mxViewWindow
, UNO_QUERY
);
482 if (mxPointer
.is() && xPeer
.is())
484 mxPointer
->setType(nPointerShape
);
485 xPeer
->setPointer(mxPointer
);
489 awt::Rectangle SAL_CALL
PresenterSlideShowView::getCanvasArea( ) throw (RuntimeException
, std::exception
)
491 if( mxViewWindow
.is() && mxTopPane
.is() )
492 return mxPresenterHelper
->getWindowExtentsRelative( mxViewWindow
, mxTopPane
->getWindow() );
494 awt::Rectangle aRectangle
;
496 aRectangle
.X
= aRectangle
.Y
= aRectangle
.Width
= aRectangle
.Height
= 0;
501 //----- lang::XEventListener --------------------------------------------------
503 void SAL_CALL
PresenterSlideShowView::disposing (const lang::EventObject
& rEvent
)
504 throw (RuntimeException
, std::exception
)
506 if (rEvent
.Source
== mxViewWindow
)
508 else if (rEvent
.Source
== mxSlideShow
)
512 //----- XPaintListener --------------------------------------------------------
514 void SAL_CALL
PresenterSlideShowView::windowPaint (const awt::PaintEvent
& rEvent
)
515 throw (RuntimeException
, std::exception
)
517 // Deactivated views must not be painted.
518 if ( ! mbIsPresenterViewActive
)
521 awt::Rectangle
aViewWindowBox (mxViewWindow
->getPosSize());
522 if (aViewWindowBox
.Width
<= 0 || aViewWindowBox
.Height
<= 0)
525 if (rEvent
.Source
== mxWindow
)
526 PaintOuterWindow(rEvent
.UpdateRect
);
527 else if (mbIsEndSlideVisible
)
528 PaintEndSlide(rEvent
.UpdateRect
);
530 PaintInnerWindow(rEvent
);
533 //----- XMouseListener --------------------------------------------------------
535 void SAL_CALL
PresenterSlideShowView::mousePressed (const awt::MouseEvent
& rEvent
)
536 throw (RuntimeException
, std::exception
)
538 awt::MouseEvent
aEvent (rEvent
);
539 aEvent
.Source
= static_cast<XWeak
*>(this);
540 ::cppu::OInterfaceContainerHelper
* pIterator
541 = maBroadcaster
.getContainer(cppu::UnoType
<awt::XMouseListener
>::get());
542 if (pIterator
!= NULL
)
544 pIterator
->notifyEach(&awt::XMouseListener::mousePressed
, aEvent
);
547 // Only when the end slide is displayed we forward the mouse event to
548 // the PresenterController so that it switches to the next slide and
549 // ends the presentation.
550 if (mbIsEndSlideVisible
)
551 if (mpPresenterController
.get() != NULL
)
552 mpPresenterController
->HandleMouseClick(rEvent
);
555 void SAL_CALL
PresenterSlideShowView::mouseReleased (const awt::MouseEvent
& rEvent
)
556 throw (RuntimeException
, std::exception
)
558 awt::MouseEvent
aEvent (rEvent
);
559 aEvent
.Source
= static_cast<XWeak
*>(this);
560 ::cppu::OInterfaceContainerHelper
* pIterator
561 = maBroadcaster
.getContainer(cppu::UnoType
<awt::XMouseListener
>::get());
562 if (pIterator
!= NULL
)
564 pIterator
->notifyEach(&awt::XMouseListener::mouseReleased
, aEvent
);
568 void SAL_CALL
PresenterSlideShowView::mouseEntered (const awt::MouseEvent
& rEvent
)
569 throw (RuntimeException
, std::exception
)
571 awt::MouseEvent
aEvent (rEvent
);
572 aEvent
.Source
= static_cast<XWeak
*>(this);
573 ::cppu::OInterfaceContainerHelper
* pIterator
574 = maBroadcaster
.getContainer(cppu::UnoType
<awt::XMouseListener
>::get());
575 if (pIterator
!= NULL
)
577 pIterator
->notifyEach(&awt::XMouseListener::mouseEntered
, aEvent
);
581 void SAL_CALL
PresenterSlideShowView::mouseExited (const awt::MouseEvent
& rEvent
)
582 throw (RuntimeException
, std::exception
)
584 awt::MouseEvent
aEvent (rEvent
);
585 aEvent
.Source
= static_cast<XWeak
*>(this);
586 ::cppu::OInterfaceContainerHelper
* pIterator
587 = maBroadcaster
.getContainer(cppu::UnoType
<awt::XMouseListener
>::get());
588 if (pIterator
!= NULL
)
590 pIterator
->notifyEach(&awt::XMouseListener::mouseExited
, aEvent
);
594 //----- XMouseMotionListener --------------------------------------------------
596 void SAL_CALL
PresenterSlideShowView::mouseDragged (const awt::MouseEvent
& rEvent
)
597 throw (RuntimeException
, std::exception
)
599 awt::MouseEvent
aEvent (rEvent
);
600 aEvent
.Source
= static_cast<XWeak
*>(this);
601 ::cppu::OInterfaceContainerHelper
* pIterator
602 = maBroadcaster
.getContainer(cppu::UnoType
<awt::XMouseMotionListener
>::get());
603 if (pIterator
!= NULL
)
605 pIterator
->notifyEach(&awt::XMouseMotionListener::mouseDragged
, aEvent
);
609 void SAL_CALL
PresenterSlideShowView::mouseMoved (const awt::MouseEvent
& rEvent
)
610 throw (RuntimeException
, std::exception
)
612 awt::MouseEvent
aEvent (rEvent
);
613 aEvent
.Source
= static_cast<XWeak
*>(this);
614 ::cppu::OInterfaceContainerHelper
* pIterator
615 = maBroadcaster
.getContainer(cppu::UnoType
<awt::XMouseMotionListener
>::get());
616 if (pIterator
!= NULL
)
618 pIterator
->notifyEach(&awt::XMouseMotionListener::mouseMoved
, aEvent
);
622 //----- XWindowListener -------------------------------------------------------
624 void SAL_CALL
PresenterSlideShowView::windowResized (const awt::WindowEvent
& rEvent
)
625 throw (RuntimeException
, std::exception
)
630 ::osl::MutexGuard
aGuard (::osl::Mutex::getGlobalMutex());
635 void SAL_CALL
PresenterSlideShowView::windowMoved (const awt::WindowEvent
& rEvent
)
636 throw (RuntimeException
, std::exception
)
639 if ( ! mbIsPaintPending
)
640 mbIsForcedPaintPending
= true;
643 void SAL_CALL
PresenterSlideShowView::windowShown (const lang::EventObject
& rEvent
)
644 throw (RuntimeException
, std::exception
)
650 void SAL_CALL
PresenterSlideShowView::windowHidden (const lang::EventObject
& rEvent
)
651 throw (RuntimeException
, std::exception
)
656 //----- XView -----------------------------------------------------------------
658 Reference
<XResourceId
> SAL_CALL
PresenterSlideShowView::getResourceId()
659 throw(RuntimeException
, std::exception
)
664 sal_Bool SAL_CALL
PresenterSlideShowView::isAnchorOnly()
665 throw (RuntimeException
, std::exception
)
670 //----- CachablePresenterView -------------------------------------------------
672 void PresenterSlideShowView::ActivatePresenterView()
674 if (mxSlideShow
.is() && ! mbIsViewAdded
)
676 impl_addAndConfigureView();
677 mbIsViewAdded
= true;
681 void PresenterSlideShowView::DeactivatePresenterView()
683 if (mxSlideShow
.is() && mbIsViewAdded
)
685 mxSlideShow
->removeView(this);
686 mbIsViewAdded
= false;
692 void PresenterSlideShowView::PaintOuterWindow (const awt::Rectangle
& rRepaintBox
)
694 if ( ! mxCanvas
.is())
697 if (mpBackground
.get() == NULL
)
700 const rendering::ViewState
aViewState(
701 geometry::AffineMatrix2D(1,0,0, 0,1,0),
702 PresenterGeometryHelper::CreatePolygon(rRepaintBox
, mxCanvas
->getDevice()));
704 rendering::RenderState
aRenderState (
705 geometry::AffineMatrix2D(1,0,0, 0,1,0),
708 rendering::CompositeOperation::SOURCE
);
710 Reference
<rendering::XBitmap
> xBackgroundBitmap (mpBackground
->GetNormalBitmap());
711 if (xBackgroundBitmap
.is())
713 Sequence
<rendering::Texture
> aTextures (1);
714 const geometry::IntegerSize2D
aBitmapSize(xBackgroundBitmap
->getSize());
715 aTextures
[0] = rendering::Texture (
716 geometry::AffineMatrix2D(
717 aBitmapSize
.Width
,0,0,
718 0,aBitmapSize
.Height
,0),
724 rendering::StrokeAttributes(),
725 rendering::TexturingMode::REPEAT
,
726 rendering::TexturingMode::REPEAT
);
728 if (mxBackgroundPolygon1
.is())
729 mxCanvas
->fillTexturedPolyPolygon(
730 mxBackgroundPolygon1
,
734 if (mxBackgroundPolygon2
.is())
735 mxCanvas
->fillTexturedPolyPolygon(
736 mxBackgroundPolygon2
,
743 PresenterCanvasHelper::SetDeviceColor(aRenderState
, mpBackground
->maReplacementColor
);
745 if (mxBackgroundPolygon1
.is())
746 mxCanvas
->fillPolyPolygon(mxBackgroundPolygon1
, aViewState
, aRenderState
);
747 if (mxBackgroundPolygon2
.is())
748 mxCanvas
->fillPolyPolygon(mxBackgroundPolygon2
, aViewState
, aRenderState
);
752 void PresenterSlideShowView::PaintEndSlide (const awt::Rectangle
& rRepaintBox
)
754 if ( ! mxCanvas
.is())
757 const rendering::ViewState
aViewState(
758 geometry::AffineMatrix2D(1,0,0, 0,1,0),
759 PresenterGeometryHelper::CreatePolygon(rRepaintBox
, mxCanvas
->getDevice()));
761 rendering::RenderState
aRenderState (
762 geometry::AffineMatrix2D(1,0,0, 0,1,0),
765 rendering::CompositeOperation::SOURCE
);
766 PresenterCanvasHelper::SetDeviceColor(aRenderState
, util::Color(0x00000000));
767 mxCanvas
->fillPolyPolygon(
768 PresenterGeometryHelper::CreatePolygon(mxViewWindow
->getPosSize(), mxCanvas
->getDevice()),
774 if (mpPresenterController
.get() == NULL
)
776 ::boost::shared_ptr
<PresenterTheme
> pTheme (mpPresenterController
->GetTheme());
777 if (pTheme
.get() == NULL
)
780 const OUString
sViewStyle (pTheme
->GetStyleName(mxViewId
->getResourceURL()));
781 PresenterTheme::SharedFontDescriptor
pFont (pTheme
->GetFont(sViewStyle
));
782 if (pFont
.get() == NULL
)
785 /// this is responsible of the " presentation exit " text inside the slide windows
786 PresenterCanvasHelper::SetDeviceColor(aRenderState
, util::Color(0x00ffffff));
787 aRenderState
.AffineTransform
.m02
= 20;
788 aRenderState
.AffineTransform
.m12
= 40;
789 const rendering::StringContext
aContext (
790 msClickToExitPresentationText
, 0, msClickToExitPresentationText
.getLength());
791 pFont
->PrepareFont(mxCanvas
);
792 const Reference
<rendering::XTextLayout
> xLayout (
793 pFont
->mxFont
->createTextLayout(aContext
,rendering::TextDirection::WEAK_LEFT_TO_RIGHT
,0));
794 mxCanvas
->drawTextLayout(
801 // Finally, in double buffered environments, request the changes to be
803 Reference
<rendering::XSpriteCanvas
> mxSpriteCanvas (mxCanvas
, UNO_QUERY
);
804 if (mxSpriteCanvas
.is())
805 mxSpriteCanvas
->updateScreen(sal_True
);
808 void PresenterSlideShowView::PaintInnerWindow (const awt::PaintEvent
& rEvent
)
810 // Forward window paint to listeners.
811 awt::PaintEvent
aEvent (rEvent
);
812 aEvent
.Source
= static_cast<XWeak
*>(this);
813 ::cppu::OInterfaceContainerHelper
* pIterator
814 = maBroadcaster
.getContainer(cppu::UnoType
<awt::XPaintListener
>::get());
815 if (pIterator
!= NULL
)
817 pIterator
->notifyEach(&awt::XPaintListener::windowPaint
, aEvent
);
820 if (mbIsForcedPaintPending
)
823 // Finally, in double buffered environments, request the changes to be
825 Reference
<rendering::XSpriteCanvas
> mxSpriteCanvas (mxCanvas
, UNO_QUERY
);
826 if (mxSpriteCanvas
.is())
827 mxSpriteCanvas
->updateScreen(sal_True
);
830 Reference
<awt::XWindow
> PresenterSlideShowView::CreateViewWindow (
831 const Reference
<awt::XWindow
>& rxParentWindow
) const
833 Reference
<awt::XWindow
> xViewWindow
;
836 Reference
<lang::XMultiComponentFactory
> xFactory (mxComponentContext
->getServiceManager());
837 if ( ! xFactory
.is())
840 Reference
<awt::XToolkit2
> xToolkit
= awt::Toolkit::create(mxComponentContext
);
841 awt::WindowDescriptor
aWindowDescriptor (
842 awt::WindowClass_CONTAINER
,
844 Reference
<awt::XWindowPeer
>(rxParentWindow
,UNO_QUERY_THROW
),
845 -1, // parent index not available
846 awt::Rectangle(0,0,10,10),
847 awt::WindowAttribute::SIZEABLE
848 | awt::WindowAttribute::MOVEABLE
849 | awt::WindowAttribute::NODECORATION
);
850 xViewWindow
= Reference
<awt::XWindow
>(
851 xToolkit
->createWindow(aWindowDescriptor
),UNO_QUERY_THROW
);
853 // Make the background transparent. The slide show paints its own background.
854 Reference
<awt::XWindowPeer
> xPeer (xViewWindow
, UNO_QUERY_THROW
);
857 xPeer
->setBackground(0xff000000);
860 xViewWindow
->setVisible(sal_True
);
862 catch (RuntimeException
&)
868 Reference
<rendering::XCanvas
> PresenterSlideShowView::CreateViewCanvas (
869 const Reference
<awt::XWindow
>& rxViewWindow
) const
871 // Create a canvas for the view window.
872 return mxPresenterHelper
->createSharedCanvas(
873 Reference
<rendering::XSpriteCanvas
>(mxTopPane
->getCanvas(), UNO_QUERY
),
874 mxTopPane
->getWindow(),
875 mxTopPane
->getCanvas(),
876 mxTopPane
->getWindow(),
880 void PresenterSlideShowView::Resize()
882 if ( ! mxWindow
.is() || ! mxViewWindow
.is())
885 const awt::Rectangle
aWindowBox (mxWindow
->getPosSize());
886 awt::Rectangle aViewWindowBox
;
887 if (aWindowBox
.Height
> 0)
889 const double nWindowAspectRatio (
890 double(aWindowBox
.Width
) / double(aWindowBox
.Height
));
891 if (nWindowAspectRatio
> mnPageAspectRatio
)
893 // Slides will be painted with the full parent window height.
894 aViewWindowBox
.Width
= sal_Int32(aWindowBox
.Height
* mnPageAspectRatio
+ 0.5);
895 aViewWindowBox
.Height
= aWindowBox
.Height
;
896 aViewWindowBox
.X
= (aWindowBox
.Width
- aViewWindowBox
.Width
) / 2;
897 aViewWindowBox
.Y
= 0;
901 // Slides will be painted with the full parent window width.
902 aViewWindowBox
.Width
= aWindowBox
.Width
;
903 aViewWindowBox
.Height
= sal_Int32(aWindowBox
.Width
/ mnPageAspectRatio
+ 0.5);
904 aViewWindowBox
.X
= 0;
905 aViewWindowBox
.Y
= (aWindowBox
.Height
- aViewWindowBox
.Height
) / 2;
907 mxViewWindow
->setPosSize(
910 aViewWindowBox
.Width
,
911 aViewWindowBox
.Height
,
912 awt::PosSize::POSSIZE
);
915 // Clear the background polygon so that on the next paint it is created
917 CreateBackgroundPolygons();
919 // Notify listeners that the transformation that maps the view into the
920 // window has changed.
921 lang::EventObject
aEvent (static_cast<XWeak
*>(this));
922 ::cppu::OInterfaceContainerHelper
* pIterator
923 = maBroadcaster
.getContainer(cppu::UnoType
<util::XModifyListener
>::get());
924 if (pIterator
!= NULL
)
926 pIterator
->notifyEach(&util::XModifyListener::modified
, aEvent
);
929 // Due to constant aspect ratio resizing may lead a preview that changes
930 // its position but not its size. This invalidates the back buffer and
931 // we have to enforce a complete repaint.
932 if ( ! mbIsPaintPending
)
933 mbIsForcedPaintPending
= true;
936 void PresenterSlideShowView::ForceRepaint()
938 if (mxSlideShow
.is() && mbIsViewAdded
)
940 mxSlideShow
->removeView(this);
941 impl_addAndConfigureView();
945 void PresenterSlideShowView::CreateBackgroundPolygons()
947 const awt::Rectangle
aWindowBox (mxWindow
->getPosSize());
948 const awt::Rectangle
aViewWindowBox (mxViewWindow
->getPosSize());
949 if (aWindowBox
.Height
== aViewWindowBox
.Height
&& aWindowBox
.Width
== aViewWindowBox
.Width
)
951 mxBackgroundPolygon1
= NULL
;
952 mxBackgroundPolygon2
= NULL
;
954 else if (aWindowBox
.Height
== aViewWindowBox
.Height
)
956 // Paint two boxes to the left and right of the view window.
957 mxBackgroundPolygon1
= PresenterGeometryHelper::CreatePolygon(
963 mxCanvas
->getDevice());
964 mxBackgroundPolygon2
= PresenterGeometryHelper::CreatePolygon(
966 aViewWindowBox
.X
+ aViewWindowBox
.Width
,
968 aWindowBox
.Width
- aViewWindowBox
.X
- aViewWindowBox
.Width
,
970 mxCanvas
->getDevice());
974 // Paint two boxes above and below the view window.
975 mxBackgroundPolygon1
= PresenterGeometryHelper::CreatePolygon(
981 mxCanvas
->getDevice());
982 mxBackgroundPolygon2
= PresenterGeometryHelper::CreatePolygon(
985 aViewWindowBox
.Y
+ aViewWindowBox
.Height
,
987 aWindowBox
.Height
- aViewWindowBox
.Y
- aViewWindowBox
.Height
),
988 mxCanvas
->getDevice());
992 void PresenterSlideShowView::ThrowIfDisposed()
993 throw (::com::sun::star::lang::DisposedException
)
995 if (rBHelper
.bDisposed
|| rBHelper
.bInDispose
)
997 throw lang::DisposedException (
998 OUString("PresenterSlideShowView object has already been disposed"),
999 static_cast<uno::XWeak
*>(this));
1003 void PresenterSlideShowView::impl_addAndConfigureView()
1005 Reference
<presentation::XSlideShowView
> xView (this);
1006 mxSlideShow
->addView(xView
);
1007 // Prevent embedded sounds being played twice at the same time by
1008 // disabling sound for the new slide show view.
1009 beans::PropertyValue aProperty
;
1010 aProperty
.Name
= "IsSoundEnabled";
1011 Sequence
<Any
> aValues (2);
1012 aValues
[0] <<= xView
;
1013 aValues
[1] <<= sal_False
;
1014 aProperty
.Value
<<= aValues
;
1015 mxSlideShow
->setProperty(aProperty
);
1018 } } // end of namespace ::sd::presenter
1020 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */