LibreOffice Module sd (master) 1
PresenterSlideShowView.cxx
Go to the documentation of this file.
1
2/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3/*
4 * This file is part of the LibreOffice project.
5 *
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/.
9 *
10 * This file incorporates work covered by the following license notice:
11 *
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 .
19 */
20
24#include "PresenterHelper.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>
40#include <utility>
41
42using namespace ::com::sun::star;
43using namespace ::com::sun::star::uno;
45
46namespace sdext::presenter {
47
48//===== PresenterSlideShowView ================================================
49
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)
56 mxComponentContext(std::move(xContext)),
57 mpPresenterController(std::move(xPresenterController)),
58 mxViewId(std::move(xViewId)),
59 mxController(rxController),
60 mxSlideShowController(PresenterHelper::GetSlideShowController(rxController)),
61 mbIsViewAdded(false),
62 mnPageAspectRatio(28.0/21.0),
63 maBroadcaster(m_aMutex),
64 mbIsForcedPaintPending(false),
65 mbIsPaintPending(true),
66 mbIsEndSlideVisible(false)
67{
69 {
70 mnPageAspectRatio = mpPresenterController->GetSlideAspectRatio();
71 mpBackground = mpPresenterController->GetViewBackground(mxViewId->getResourceURL());
72 }
73}
74
76{
77 mxSlideShow.set( mxSlideShowController->getSlideShow(), UNO_SET_THROW);
78 Reference<lang::XComponent> xSlideShowComponent (mxSlideShow, UNO_QUERY);
79 xSlideShowComponent->addEventListener(static_cast<awt::XWindowListener*>(this));
80
81 Reference<lang::XMultiComponentFactory> xFactory (
82 mxComponentContext->getServiceManager(), UNO_SET_THROW);
83 mxPresenterHelper.set (xFactory->createInstanceWithContext(
84 "com.sun.star.comp.Draw.PresenterHelper",
86 UNO_QUERY_THROW);
87
88 // Use view id and controller to retrieve window and canvas from
89 // configuration controller.
90 Reference<XConfigurationController> xCC (mxController->getConfigurationController());
91
92 if (xCC.is())
93 {
94 mxTopPane.set(xCC->getResource(mxViewId->getAnchor()->getAnchor()), UNO_QUERY);
95
96 Reference<XPane> xPane (xCC->getResource(mxViewId->getAnchor()), UNO_QUERY_THROW);
97
98 mxWindow = xPane->getWindow();
99 mxCanvas = xPane->getCanvas();
100
101 if (mxWindow.is())
102 {
103 mxWindow->addPaintListener(this);
104 mxWindow->addWindowListener(this);
105 }
106
107 // The window does not have to paint a background. We do
108 // that ourself.
109 Reference<awt::XWindowPeer> xPeer (mxWindow, UNO_QUERY);
110 if (xPeer.is())
111 xPeer->setBackground(util::Color(0xff000000));
112 }
113
114 // Create a window for the actual slide show view. It is places
115 // centered and with maximal size inside the pane.
117
119
120 if (mxViewWindow.is())
121 {
122 // Register listeners at window.
123 mxViewWindow->addPaintListener(this);
124 mxViewWindow->addMouseListener(this);
125 mxViewWindow->addMouseMotionListener(this);
126 }
127
128 if (mxViewWindow.is())
129 Resize();
130
131 if (mxWindow.is())
132 mxWindow->setVisible(true);
133
134 // Add the new slide show view to the slide show.
135 if (mxSlideShow.is() && ! mbIsViewAdded)
136 {
138 mbIsViewAdded = true;
139 }
140
141 // Read text for one past last slide.
142 PresenterConfigurationAccess aConfiguration (
146 aConfiguration.GetConfigurationNode(
147 "Presenter/Views/CurrentSlidePreview/"
148 "Strings/ClickToExitPresentationText/String")
150 aConfiguration.GetConfigurationNode(
151 "Presenter/Views/CurrentSlidePreview/"
152 "Strings/ClickToExitPresentationTitle/String")
154}
155
157{
158}
159
161{
162 // Tell all listeners that we are disposed.
163 lang::EventObject aEvent;
164 aEvent.Source = static_cast<XWeak*>(this);
165
168 if (pIterator != nullptr)
169 pIterator->disposeAndClear(aEvent);
170
171 // Do this for
172 // XPaintListener, XModifyListener,XMouseListener,XMouseMotionListener,XWindowListener?
173
174 if (mxWindow.is())
175 {
176 mxWindow->removePaintListener(this);
177 mxWindow->removeMouseListener(this);
178 mxWindow->removeMouseMotionListener(this);
179 mxWindow->removeWindowListener(this);
180 mxWindow = nullptr;
181 }
182 mxSlideShowController = nullptr;
183 mxSlideShow = nullptr;
184 if (mxViewCanvas.is())
185 {
186 Reference<XComponent> xComponent (mxViewCanvas, UNO_QUERY);
187 mxViewCanvas = nullptr;
188 if (xComponent.is())
189 xComponent->dispose();
190 }
191 if (mxViewWindow.is())
192 {
193 Reference<XComponent> xComponent = mxViewWindow;
194 mxViewWindow = nullptr;
195 if (xComponent.is())
196 xComponent->dispose();
197 }
198 if (mxPointer.is())
199 {
200 Reference<XComponent> xComponent (mxPointer, UNO_QUERY);
201 mxPointer = nullptr;
202 if (xComponent.is())
203 xComponent->dispose();
204 }
205 if (mxBackgroundPolygon1.is())
206 {
207 Reference<XComponent> xComponent (mxBackgroundPolygon1, UNO_QUERY);
208 mxBackgroundPolygon1 = nullptr;
209 if (xComponent.is())
210 xComponent->dispose();
211 }
212 if (mxBackgroundPolygon2.is())
213 {
214 Reference<XComponent> xComponent (mxBackgroundPolygon2, UNO_QUERY);
215 mxBackgroundPolygon2 = nullptr;
216 if (xComponent.is())
217 xComponent->dispose();
218 }
219
220 mxComponentContext = nullptr;
221 mpPresenterController = nullptr;
222 mxViewId = nullptr;
223 mxController = nullptr;
224 mxCanvas = nullptr;
225 mpBackground.reset();
228 msTitleTemplate.clear();
229 mxCurrentSlide = nullptr;
230}
231
232//----- XDrawView -------------------------------------------------------------
233
235 const css::uno::Reference<css::drawing::XDrawPage>& rxSlide)
236{
237 mxCurrentSlide = rxSlide;
240 && ! mpPresenterController->GetCurrentSlide().is()
241 && ! mxSlideShowController->isPaused())
242 {
243 mbIsEndSlideVisible = true;
244 Reference<awt::XWindowPeer> xPeer (mxViewWindow, UNO_QUERY);
245 if (xPeer.is())
246 xPeer->invalidate(awt::InvalidateStyle::NOTRANSPARENT);
247
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
250 // backwards.
252 mpPresenterController->GetPaneContainer()->FindViewURL(mxViewId->getResourceURL()));
253 if (pDescriptor)
254 {
255 msTitleTemplate = pDescriptor->msTitleTemplate;
256 pDescriptor->msTitleTemplate = msClickToExitPresentationTitle;
257 mpPresenterController->UpdatePaneTitles();
258 }
259 }
260 else if (mbIsEndSlideVisible)
261 {
262 mbIsEndSlideVisible = false;
263
264 // Restore the title template.
266 mpPresenterController->GetPaneContainer()->FindViewURL(mxViewId->getResourceURL()));
267 if (pDescriptor)
268 {
269 pDescriptor->msTitleTemplate = msTitleTemplate;
270 pDescriptor->msTitle.clear();
271 mpPresenterController->UpdatePaneTitles();
272 }
273 }
274}
275
276css::uno::Reference<css::drawing::XDrawPage> SAL_CALL PresenterSlideShowView::getCurrentPage()
277{
278 return mxCurrentSlide;
279}
280
281//----- CachablePresenterView -------------------------------------------------
282
284{
285 if (mxSlideShow.is() && mbIsViewAdded)
286 {
287 mxSlideShow->removeView(this);
288 mbIsViewAdded = false;
289 }
290}
291
292//----- XSlideShowView --------------------------------------------------------
293
294Reference<rendering::XSpriteCanvas> SAL_CALL PresenterSlideShowView::getCanvas()
295{
297
298 return Reference<rendering::XSpriteCanvas>(mxViewCanvas, UNO_QUERY);
299}
300
302{
305 mbIsPaintPending = false;
306
307 if (!(mxViewCanvas.is() && mxViewWindow.is()))
308 return;
309
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()));
315
316 rendering::ViewState aViewState (
317 geometry::AffineMatrix2D(1,0,0, 0,1,0),
318 nullptr);
319 double const aColor[4] = {0,0,0,0};
320 rendering::RenderState aRenderState(
321 geometry::AffineMatrix2D(1,0,0, 0,1,0),
322 nullptr,
323 Sequence<double>(aColor,4),
324 rendering::CompositeOperation::SOURCE);
325 mxViewCanvas->fillPolyPolygon(xPolygon, aViewState, aRenderState);
326}
327
328geometry::AffineMatrix2D SAL_CALL PresenterSlideShowView::getTransformation()
329{
331
332 if (mxViewWindow.is())
333 {
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
342 // position.)
343 const awt::Rectangle aWindowBox = mxViewWindow->getPosSize();
344 return geometry::AffineMatrix2D(
345 aWindowBox.Width-1, 0, 0,
346 0, aWindowBox.Height-1, 0);
347 }
348 else
349 {
350 return geometry::AffineMatrix2D(1,0,0, 0,1,0);
351 }
352}
353
354geometry::IntegerSize2D SAL_CALL PresenterSlideShowView::getTranslationOffset()
355{
357 return geometry::IntegerSize2D(0,0);
358}
359
361 const Reference<util::XModifyListener>& rxListener)
362{
366 rxListener);
367}
368
370 const Reference<util::XModifyListener>& rxListener)
371{
375 rxListener);
376}
377
379 const Reference<awt::XPaintListener>& rxListener)
380{
384 rxListener);
385}
386
388 const Reference<awt::XPaintListener>& rxListener)
389{
393 rxListener);
394}
395
397 const Reference<awt::XMouseListener>& rxListener)
398{
402 rxListener);
403}
404
406 const Reference<awt::XMouseListener>& rxListener)
407{
411 rxListener);
412}
413
415 const Reference<awt::XMouseMotionListener>& rxListener)
416{
420 rxListener);
421}
422
424 const Reference<awt::XMouseMotionListener>& rxListener)
425{
429 rxListener);
430}
431
432void SAL_CALL PresenterSlideShowView::setMouseCursor(::sal_Int16 nPointerShape)
433{
435
436 // Create a pointer when it does not yet exist.
437 if ( ! mxPointer.is())
438 {
439 mxPointer = awt::Pointer::create(mxComponentContext);
440 }
441
442 // Set the pointer to the given shape and the window(peer) to the
443 // pointer.
444 Reference<awt::XWindowPeer> xPeer (mxViewWindow, UNO_QUERY);
445 if (mxPointer.is() && xPeer.is())
446 {
447 mxPointer->setType(nPointerShape);
448 xPeer->setPointer(mxPointer);
449 }
450}
451
453{
454 if( mxViewWindow.is() && mxTopPane.is() )
455 return mxPresenterHelper->getWindowExtentsRelative( mxViewWindow, mxTopPane->getWindow() );
456
457 awt::Rectangle aRectangle;
458
459 aRectangle.X = aRectangle.Y = aRectangle.Width = aRectangle.Height = 0;
460
461 return aRectangle;
462}
463
464//----- lang::XEventListener --------------------------------------------------
465
466void SAL_CALL PresenterSlideShowView::disposing (const lang::EventObject& rEvent)
467{
468 if (rEvent.Source == mxViewWindow)
469 mxViewWindow = nullptr;
470 else if (rEvent.Source == mxSlideShow)
471 mxSlideShow = nullptr;
472}
473
474//----- XPaintListener --------------------------------------------------------
475
476void SAL_CALL PresenterSlideShowView::windowPaint (const awt::PaintEvent& rEvent)
477{
478 // Deactivated views must not be painted.
479 if ( ! mbIsPresenterViewActive)
480 return;
481
482 awt::Rectangle aViewWindowBox (mxViewWindow->getPosSize());
483 if (aViewWindowBox.Width <= 0 || aViewWindowBox.Height <= 0)
484 return;
485
486 if (rEvent.Source == mxWindow)
487 PaintOuterWindow(rEvent.UpdateRect);
488 else if (mbIsEndSlideVisible)
489 PaintEndSlide(rEvent.UpdateRect);
490 else
491 PaintInnerWindow(rEvent);
492}
493
494//----- XMouseListener --------------------------------------------------------
495
496void SAL_CALL PresenterSlideShowView::mousePressed (const awt::MouseEvent& rEvent)
497{
498 awt::MouseEvent aEvent (rEvent);
499 aEvent.Source = static_cast<XWeak*>(this);
502 if (pIterator != nullptr)
503 {
504 pIterator->notifyEach(&awt::XMouseListener::mousePressed, aEvent);
505 }
506
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.
512 mpPresenterController->HandleMouseClick(rEvent);
513}
514
515void SAL_CALL PresenterSlideShowView::mouseReleased (const awt::MouseEvent& rEvent)
516{
517 awt::MouseEvent aEvent (rEvent);
518 aEvent.Source = static_cast<XWeak*>(this);
521 if (pIterator != nullptr)
522 {
523 pIterator->notifyEach(&awt::XMouseListener::mouseReleased, aEvent);
524 }
525}
526
527void SAL_CALL PresenterSlideShowView::mouseEntered (const awt::MouseEvent& rEvent)
528{
529 awt::MouseEvent aEvent (rEvent);
530 aEvent.Source = static_cast<XWeak*>(this);
533 if (pIterator != nullptr)
534 {
535 pIterator->notifyEach(&awt::XMouseListener::mouseEntered, aEvent);
536 }
537}
538
539void SAL_CALL PresenterSlideShowView::mouseExited (const awt::MouseEvent& rEvent)
540{
541 awt::MouseEvent aEvent (rEvent);
542 aEvent.Source = static_cast<XWeak*>(this);
545 if (pIterator != nullptr)
546 {
547 pIterator->notifyEach(&awt::XMouseListener::mouseExited, aEvent);
548 }
549}
550
551//----- XMouseMotionListener --------------------------------------------------
552
553void SAL_CALL PresenterSlideShowView::mouseDragged (const awt::MouseEvent& rEvent)
554{
555 awt::MouseEvent aEvent (rEvent);
556 aEvent.Source = static_cast<XWeak*>(this);
559 if (pIterator != nullptr)
560 {
561 pIterator->notifyEach(&awt::XMouseMotionListener::mouseDragged, aEvent);
562 }
563}
564
565void SAL_CALL PresenterSlideShowView::mouseMoved (const awt::MouseEvent& rEvent)
566{
567 awt::MouseEvent aEvent (rEvent);
568 aEvent.Source = static_cast<XWeak*>(this);
571 if (pIterator != nullptr)
572 {
573 pIterator->notifyEach(&awt::XMouseMotionListener::mouseMoved, aEvent);
574 }
575}
576
577//----- XWindowListener -------------------------------------------------------
578
579void SAL_CALL PresenterSlideShowView::windowResized (const awt::WindowEvent&)
580{
582 ::osl::MutexGuard aGuard (::osl::Mutex::getGlobalMutex());
583
584 Resize();
585}
586
587void SAL_CALL PresenterSlideShowView::windowMoved (const awt::WindowEvent&)
588{
589 if ( ! mbIsPaintPending)
591}
592
593void SAL_CALL PresenterSlideShowView::windowShown (const lang::EventObject&)
594{
595 Resize();
596}
597
598void SAL_CALL PresenterSlideShowView::windowHidden (const lang::EventObject&) {}
599
600//----- XView -----------------------------------------------------------------
601
602Reference<XResourceId> SAL_CALL PresenterSlideShowView::getResourceId()
603{
604 return mxViewId;
605}
606
608{
609 return false;
610}
611
612//----- CachablePresenterView -------------------------------------------------
613
615{
616 if (mxSlideShow.is() && ! mbIsViewAdded)
617 {
619 mbIsViewAdded = true;
620 }
621}
622
624{
625 if (mxSlideShow.is() && mbIsViewAdded)
626 {
627 mxSlideShow->removeView(this);
628 mbIsViewAdded = false;
629 }
630}
631
632
633void PresenterSlideShowView::PaintOuterWindow (const awt::Rectangle& rRepaintBox)
634{
635 if ( ! mxCanvas.is())
636 return;
637
638 if (!mpBackground)
639 return;
640
641 const rendering::ViewState aViewState(
642 geometry::AffineMatrix2D(1,0,0, 0,1,0),
643 PresenterGeometryHelper::CreatePolygon(rRepaintBox, mxCanvas->getDevice()));
644
645 rendering::RenderState aRenderState (
646 geometry::AffineMatrix2D(1,0,0, 0,1,0),
647 nullptr,
648 Sequence<double>(4),
649 rendering::CompositeOperation::SOURCE);
650
651 Reference<rendering::XBitmap> xBackgroundBitmap (mpBackground->GetNormalBitmap());
652 if (xBackgroundBitmap.is())
653 {
654 const geometry::IntegerSize2D aBitmapSize(xBackgroundBitmap->getSize());
655 Sequence<rendering::Texture> aTextures
656 {
657 {
658 geometry::AffineMatrix2D( aBitmapSize.Width,0,0, 0,aBitmapSize.Height,0),
659 1,
660 0,
661 xBackgroundBitmap,
662 nullptr,
663 nullptr,
664 rendering::StrokeAttributes(),
665 rendering::TexturingMode::REPEAT,
666 rendering::TexturingMode::REPEAT
667 }
668 };
669
670 if (mxBackgroundPolygon1.is())
671 mxCanvas->fillTexturedPolyPolygon(
673 aViewState,
674 aRenderState,
675 aTextures);
676 if (mxBackgroundPolygon2.is())
677 mxCanvas->fillTexturedPolyPolygon(
679 aViewState,
680 aRenderState,
681 aTextures);
682 }
683 else
684 {
685 PresenterCanvasHelper::SetDeviceColor(aRenderState, mpBackground->maReplacementColor);
686
687 if (mxBackgroundPolygon1.is())
688 mxCanvas->fillPolyPolygon(mxBackgroundPolygon1, aViewState, aRenderState);
689 if (mxBackgroundPolygon2.is())
690 mxCanvas->fillPolyPolygon(mxBackgroundPolygon2, aViewState, aRenderState);
691 }
692}
693
694void PresenterSlideShowView::PaintEndSlide (const awt::Rectangle& rRepaintBox)
695{
696 if ( ! mxCanvas.is())
697 return;
698
699 const rendering::ViewState aViewState(
700 geometry::AffineMatrix2D(1,0,0, 0,1,0),
701 PresenterGeometryHelper::CreatePolygon(rRepaintBox, mxCanvas->getDevice()));
702
703 rendering::RenderState aRenderState (
704 geometry::AffineMatrix2D(1,0,0, 0,1,0),
705 nullptr,
706 Sequence<double>(4),
707 rendering::CompositeOperation::SOURCE);
708 PresenterCanvasHelper::SetDeviceColor(aRenderState, util::Color(0x00000000));
709 mxCanvas->fillPolyPolygon(
711 aViewState,
712 aRenderState);
713
714 do
715 {
717 break;
718 std::shared_ptr<PresenterTheme> pTheme (mpPresenterController->GetTheme());
719 if (pTheme == nullptr)
720 break;
721
722 const OUString sViewStyle (pTheme->GetStyleName(mxViewId->getResourceURL()));
723 PresenterTheme::SharedFontDescriptor pFont (pTheme->GetFont(sViewStyle));
724 if (!pFont)
725 break;
726
728 PresenterCanvasHelper::SetDeviceColor(aRenderState, util::Color(0x00ffffff));
729 aRenderState.AffineTransform.m02 = 20;
730 aRenderState.AffineTransform.m12 = 40;
731 const rendering::StringContext aContext (
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(
737 xLayout,
738 aViewState,
739 aRenderState);
740 }
741 while (false);
742
743 // Finally, in double buffered environments, request the changes to be
744 // made visible.
745 Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY);
746 if (xSpriteCanvas.is())
747 xSpriteCanvas->updateScreen(true);
748}
749
750void PresenterSlideShowView::PaintInnerWindow (const awt::PaintEvent& rEvent)
751{
752 // Forward window paint to listeners.
753 awt::PaintEvent aEvent (rEvent);
754 aEvent.Source = static_cast<XWeak*>(this);
757 if (pIterator != nullptr)
758 {
759 pIterator->notifyEach(&awt::XPaintListener::windowPaint, aEvent);
760 }
761
767 {
768 mxSlideShow->removeView(this);
770 }
771
772 // Finally, in double buffered environments, request the changes to be
773 // made visible.
774 Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY);
775 if (xSpriteCanvas.is())
776 xSpriteCanvas->updateScreen(true);
777}
778
780 const Reference<awt::XWindow>& rxParentWindow) const
781{
782 Reference<awt::XWindow> xViewWindow;
783 try
784 {
785 Reference<lang::XMultiComponentFactory> xFactory (mxComponentContext->getServiceManager());
786 if ( ! xFactory.is())
787 return xViewWindow;
788
789 Reference<awt::XToolkit2> xToolkit = awt::Toolkit::create(mxComponentContext);
790 awt::WindowDescriptor aWindowDescriptor (
791 awt::WindowClass_CONTAINER,
792 OUString(),
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);
800
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);
804
805 xViewWindow->setVisible(true);
806 }
807 catch (RuntimeException&)
808 {
809 }
810 return xViewWindow;
811}
812
813Reference<rendering::XCanvas> PresenterSlideShowView::CreateViewCanvas (
814 const Reference<awt::XWindow>& rxViewWindow) const
815{
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(),
822 rxViewWindow);
823}
824
826{
827 if ( ! mxWindow.is() || ! mxViewWindow.is())
828 return;
829
830 const awt::Rectangle aWindowBox (mxWindow->getPosSize());
831 if (aWindowBox.Height > 0)
832 {
833 awt::Rectangle aViewWindowBox;
834 const double nWindowAspectRatio (
835 double(aWindowBox.Width) / double(aWindowBox.Height));
836 if (nWindowAspectRatio > mnPageAspectRatio)
837 {
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;
843 }
844 else
845 {
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;
851 }
852 mxViewWindow->setPosSize(
853 aViewWindowBox.X,
854 aViewWindowBox.Y,
855 aViewWindowBox.Width,
856 aViewWindowBox.Height,
857 awt::PosSize::POSSIZE);
858 }
859
860 // Clear the background polygon so that on the next paint it is created
861 // for the new size.
863
864 // Notify listeners that the transformation that maps the view into the
865 // window has changed.
866 lang::EventObject aEvent (static_cast<XWeak*>(this));
869 if (pIterator != nullptr)
870 {
871 pIterator->notifyEach(&util::XModifyListener::modified, aEvent);
872 }
873
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)
879}
880
882{
883 const awt::Rectangle aWindowBox (mxWindow->getPosSize());
884 const awt::Rectangle aViewWindowBox (mxViewWindow->getPosSize());
885 if (aWindowBox.Height == aViewWindowBox.Height && aWindowBox.Width == aViewWindowBox.Width)
886 {
887 mxBackgroundPolygon1 = nullptr;
888 mxBackgroundPolygon2 = nullptr;
889 }
890 else if (aWindowBox.Height == aViewWindowBox.Height)
891 {
892 // Paint two boxes to the left and right of the view window.
894 awt::Rectangle(
895 0,
896 0,
897 aViewWindowBox.X,
898 aWindowBox.Height),
899 mxCanvas->getDevice());
901 awt::Rectangle(
902 aViewWindowBox.X + aViewWindowBox.Width,
903 0,
904 aWindowBox.Width - aViewWindowBox.X - aViewWindowBox.Width,
905 aWindowBox.Height),
906 mxCanvas->getDevice());
907 }
908 else
909 {
910 // Paint two boxes above and below the view window.
912 awt::Rectangle(
913 0,
914 0,
915 aWindowBox.Width,
916 aViewWindowBox.Y),
917 mxCanvas->getDevice());
919 awt::Rectangle(
920 0,
921 aViewWindowBox.Y + aViewWindowBox.Height,
922 aWindowBox.Width,
923 aWindowBox.Height - aViewWindowBox.Y - aViewWindowBox.Height),
924 mxCanvas->getDevice());
925 }
926}
927
929{
930 if (rBHelper.bDisposed || rBHelper.bInDispose)
931 {
932 throw lang::DisposedException (
933 "PresenterSlideShowView object has already been disposed",
934 static_cast<uno::XWeak*>(this));
935 }
936}
937
939{
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);
949}
950
951} // end of namespace ::sd::presenter
952
953/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
rtl::Reference< PresenterController > mpPresenterController
css::uno::Reference< css::uno::XComponentContext > mxComponentContext
AnyEventRef aEvent
void SAL_CALL disposeAndClear(const css::lang::EventObject &rEvt)
void notifyEach(void(SAL_CALL ListenerT::*NotificationMethod)(const EventT &), const EventT &Event)
static void SetDeviceColor(css::rendering::RenderState &rRenderState, const css::util::Color aColor)
This class gives access to the configuration.
css::uno::Any GetConfigurationNode(const OUString &rsPathToNode)
Return a configuration node below the root of the called object.
static css::uno::Reference< css::rendering::XPolyPolygon2D > CreatePolygon(const css::awt::Rectangle &rBox, const css::uno::Reference< css::rendering::XGraphicDevice > &rxDevice)
std::shared_ptr< PaneDescriptor > SharedPaneDescriptor
virtual sal_Bool SAL_CALL isAnchorOnly() override
void PaintInnerWindow(const css::awt::PaintEvent &rEvent)
virtual void SAL_CALL mouseEntered(const css::awt::MouseEvent &rEvent) override
virtual void SAL_CALL addPaintListener(const css::uno::Reference< css::awt::XPaintListener > &xListener) override
virtual css::geometry::AffineMatrix2D SAL_CALL getTransformation() override
css::uno::Reference< css::awt::XWindow > mxWindow
virtual void SAL_CALL mouseExited(const css::awt::MouseEvent &rEvent) override
void PaintEndSlide(const css::awt::Rectangle &rRepaintBox)
virtual css::uno::Reference< css::rendering::XSpriteCanvas > SAL_CALL getCanvas() override
virtual void SAL_CALL mouseReleased(const css::awt::MouseEvent &rEvent) override
css::uno::Reference< css::presentation::XSlideShow > mxSlideShow
::rtl::Reference< PresenterController > mpPresenterController
virtual css::uno::Reference< css::drawing::XDrawPage > SAL_CALL getCurrentPage() override
css::uno::Reference< css::drawing::XPresenterHelper > mxPresenterHelper
virtual void SAL_CALL removeTransformationChangedListener(const css::uno::Reference< css::util::XModifyListener > &xListener) override
css::uno::Reference< css::uno::XComponentContext > mxComponentContext
virtual void SAL_CALL removeMouseListener(const css::uno::Reference< css::awt::XMouseListener > &xListener) override
css::uno::Reference< css::rendering::XPolyPolygon2D > mxBackgroundPolygon1
css::uno::Reference< css::rendering::XCanvas > mxViewCanvas
virtual void SAL_CALL windowResized(const css::awt::WindowEvent &rEvent) override
virtual void SAL_CALL setCurrentPage(const css::uno::Reference< css::drawing::XDrawPage > &rxSlide) override
rtl::Reference<::sd::DrawController > mxController
virtual void SAL_CALL windowPaint(const css::awt::PaintEvent &rEvent) override
css::uno::Reference< css::drawing::XDrawPage > mxCurrentSlide
css::uno::Reference< css::drawing::framework::XResourceId > mxViewId
css::uno::Reference< css::presentation::XSlideShowController > mxSlideShowController
virtual void SAL_CALL mouseDragged(const css::awt::MouseEvent &rEvent) override
virtual void SAL_CALL removePaintListener(const css::uno::Reference< css::awt::XPaintListener > &xListener) override
css::uno::Reference< css::rendering::XCanvas > CreateViewCanvas(const css::uno::Reference< css::awt::XWindow > &rxWindow) const
virtual void SAL_CALL addMouseListener(const css::uno::Reference< css::awt::XMouseListener > &xListener) override
void PaintOuterWindow(const css::awt::Rectangle &rRepaintBox)
virtual void SAL_CALL disposing() override
virtual void SAL_CALL windowHidden(const css::lang::EventObject &rEvent) override
virtual void SAL_CALL mouseMoved(const css::awt::MouseEvent &rEvent) override
::cppu::OBroadcastHelper maBroadcaster
This broadcast helper is used to notify listeners registered to a SlideShowView object.
virtual void SAL_CALL removeMouseMotionListener(const css::uno::Reference< css::awt::XMouseMotionListener > &xListener) override
virtual void SAL_CALL mousePressed(const css::awt::MouseEvent &rEvent) override
virtual css::uno::Reference< css::drawing::framework::XResourceId > SAL_CALL getResourceId() override
virtual void SAL_CALL addTransformationChangedListener(const css::uno::Reference< css::util::XModifyListener > &xListener) override
virtual css::awt::Rectangle SAL_CALL getCanvasArea() override
css::uno::Reference< css::awt::XWindow > CreateViewWindow(const css::uno::Reference< css::awt::XWindow > &rxParentWindow) const
Create the window into which the slide show will render its content.
double mnPageAspectRatio
Aspect ratio of the current slide.
virtual void SAL_CALL setMouseCursor(::sal_Int16 nPointerShape) override
css::uno::Reference< css::drawing::framework::XPane > mxTopPane
css::uno::Reference< css::rendering::XCanvas > mxCanvas
virtual void SAL_CALL windowMoved(const css::awt::WindowEvent &rEvent) override
virtual css::geometry::IntegerSize2D SAL_CALL getTranslationOffset() override
virtual void SAL_CALL windowShown(const css::lang::EventObject &rEvent) override
virtual void SAL_CALL addMouseMotionListener(const css::uno::Reference< css::awt::XMouseMotionListener > &xListener) override
css::uno::Reference< css::awt::XPointer > mxPointer
css::uno::Reference< css::awt::XWindow > mxViewWindow
css::uno::Reference< css::rendering::XPolyPolygon2D > mxBackgroundPolygon2
PresenterSlideShowView(css::uno::Reference< css::uno::XComponentContext > xContext, css::uno::Reference< css::drawing::framework::XResourceId > xViewId, const rtl::Reference<::sd::DrawController > &rxController, ::rtl::Reference< PresenterController > xPresenterController)
std::shared_ptr< FontDescriptor > SharedFontDescriptor
Reference< XSingleServiceFactory > xFactory
std::mutex m_aMutex
css::uno::Reference< css::presentation::XSlideShowController > GetSlideShowController(const css::uno::Reference< css::frame::XController > &rxController)
Return the slide show controller of a running presentation that has the same document as the given fr...
cppu::WeakComponentImplHelper< css::presentation::XSlideShowView, css::awt::XPaintListener, css::awt::XMouseListener, css::awt::XMouseMotionListener, css::awt::XWindowListener, css::drawing::framework::XView, css::drawing::XDrawView > PresenterSlideShowViewInterfaceBase
void addListener(const keyType &key, const css::uno::Reference< css::uno::XInterface > &r)
void removeListener(const keyType &key, const css::uno::Reference< css::uno::XInterface > &r)
OInterfaceContainerHelper *SAL_CALL getContainer(const keyType &key) const
unsigned char sal_Bool