1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <vcl/settings.hxx>
22 #include "PresenterWindowManager.hxx"
23 #include "PresenterController.hxx"
24 #include "PresenterGeometryHelper.hxx"
25 #include "PresenterPaintManager.hxx"
26 #include "PresenterPaneBorderPainter.hxx"
27 #include "PresenterPaneContainer.hxx"
28 #include "PresenterPaneFactory.hxx"
29 #include "PresenterToolBar.hxx"
30 #include "PresenterViewFactory.hxx"
31 #include "PresenterTheme.hxx"
32 #include <com/sun/star/awt/InvalidateStyle.hpp>
33 #include <com/sun/star/awt/PosSize.hpp>
34 #include <com/sun/star/awt/XWindow2.hpp>
35 #include <com/sun/star/awt/XWindowPeer.hpp>
36 #include <com/sun/star/rendering/CompositeOperation.hpp>
37 #include <com/sun/star/rendering/FillRule.hpp>
38 #include <com/sun/star/rendering/Texture.hpp>
39 #include <com/sun/star/rendering/TexturingMode.hpp>
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 //===== PresenterWindowManager ================================================
50 PresenterWindowManager::PresenterWindowManager (
51 const Reference
<XComponentContext
>& rxContext
,
52 ::rtl::Reference
<PresenterPaneContainer
> pPaneContainer
,
53 ::rtl::Reference
<PresenterController
> pPresenterController
)
54 : PresenterWindowManagerInterfaceBase(m_aMutex
),
55 mxComponentContext(rxContext
),
56 mpPresenterController(std::move(pPresenterController
)),
57 mpPaneContainer(std::move(pPaneContainer
)),
58 mbIsLayoutPending(true),
60 meLayoutMode(LM_Generic
),
61 mbIsSlideSorterActive(false),
62 mbIsHelpViewActive(false),
64 mbIsMouseClickPending(false)
69 PresenterWindowManager::~PresenterWindowManager()
73 void SAL_CALL
PresenterWindowManager::disposing()
77 SetParentPane(nullptr);
79 Reference
<lang::XComponent
> xComponent (mxPaneBorderManager
, UNO_QUERY
);
81 xComponent
->dispose();
82 mxPaneBorderManager
= nullptr;
84 for (const auto& rxPane
: mpPaneContainer
->maPanes
)
86 if (rxPane
->mxBorderWindow
.is())
88 rxPane
->mxBorderWindow
->removeWindowListener(this);
89 rxPane
->mxBorderWindow
->removeFocusListener(this);
90 rxPane
->mxBorderWindow
->removeMouseListener(this);
95 void PresenterWindowManager::SetParentPane (
96 const Reference
<drawing::framework::XPane
>& rxPane
)
98 if (mxParentWindow
.is())
100 mxParentWindow
->removeWindowListener(this);
101 mxParentWindow
->removePaintListener(this);
102 mxParentWindow
->removeMouseListener(this);
103 mxParentWindow
->removeFocusListener(this);
105 mxParentWindow
= nullptr;
106 mxParentCanvas
= nullptr;
110 mxParentWindow
= rxPane
->getWindow();
111 mxParentCanvas
= rxPane
->getCanvas();
115 mxParentWindow
= nullptr;
118 if (mxParentWindow
.is())
120 mxParentWindow
->addWindowListener(this);
121 mxParentWindow
->addPaintListener(this);
122 mxParentWindow
->addMouseListener(this);
123 mxParentWindow
->addFocusListener(this);
125 // We paint our own background, make that of the parent window transparent.
126 Reference
<awt::XWindowPeer
> xPeer (mxParentWindow
, UNO_QUERY
);
128 xPeer
->setBackground(util::Color(0xff000000));
132 void PresenterWindowManager::SetTheme (const std::shared_ptr
<PresenterTheme
>& rpTheme
)
136 // Get background bitmap or background color from the theme.
138 if (mpTheme
!= nullptr)
140 mpBackgroundBitmap
= mpTheme
->GetBitmap(OUString(), "Background");
144 void PresenterWindowManager::NotifyViewCreation (const Reference
<XView
>& rxView
)
146 PresenterPaneContainer::SharedPaneDescriptor
pDescriptor (
147 mpPaneContainer
->FindPaneId(rxView
->getResourceId()->getAnchor()));
148 OSL_ASSERT(pDescriptor
);
153 mpPresenterController
->GetPaintManager()->Invalidate(
154 pDescriptor
->mxContentWindow
,
155 sal_Int16(awt::InvalidateStyle::TRANSPARENT
156 | awt::InvalidateStyle::CHILDREN
));
160 void PresenterWindowManager::SetPanePosSizeAbsolute (
161 const OUString
& rsPaneURL
,
165 const double nHeight
)
167 PresenterPaneContainer::SharedPaneDescriptor
pDescriptor (
168 mpPaneContainer
->FindPaneURL(rsPaneURL
));
171 if (pDescriptor
->mxBorderWindow
.is())
172 pDescriptor
->mxBorderWindow
->setPosSize(
173 ::sal::static_int_cast
<sal_Int32
>(nX
),
174 ::sal::static_int_cast
<sal_Int32
>(nY
),
175 ::sal::static_int_cast
<sal_Int32
>(nWidth
),
176 ::sal::static_int_cast
<sal_Int32
>(nHeight
),
177 awt::PosSize::POSSIZE
);
181 void PresenterWindowManager::SetPaneBorderPainter (
182 const ::rtl::Reference
<PresenterPaneBorderPainter
>& rPainter
)
184 mpPaneBorderPainter
= rPainter
;
187 //----- XWindowListener -------------------------------------------------------
189 void SAL_CALL
PresenterWindowManager::windowResized (const awt::WindowEvent
& rEvent
)
192 if (rEvent
.Source
== mxParentWindow
)
198 Reference
<awt::XWindow
> xWindow (rEvent
.Source
,UNO_QUERY
);
201 UpdateWindowSize(xWindow
);
203 // Make sure the background of a transparent window is painted.
204 mpPresenterController
->GetPaintManager()->Invalidate(mxParentWindow
);
209 void SAL_CALL
PresenterWindowManager::windowMoved (const awt::WindowEvent
& rEvent
)
212 if (rEvent
.Source
!= mxParentWindow
)
214 Reference
<awt::XWindow
> xWindow (rEvent
.Source
,UNO_QUERY
);
215 UpdateWindowSize(xWindow
);
217 // Make sure the background of a transparent window is painted.
218 mpPresenterController
->GetPaintManager()->Invalidate(xWindow
);
222 void SAL_CALL
PresenterWindowManager::windowShown (const lang::EventObject
&) {}
224 void SAL_CALL
PresenterWindowManager::windowHidden (const lang::EventObject
&) {}
226 //----- XPaintListener --------------------------------------------------------
228 void SAL_CALL
PresenterWindowManager::windowPaint (const awt::PaintEvent
& rEvent
)
232 if ( ! mxParentWindow
.is())
234 if ( ! mxParentCanvas
.is())
237 if (mpTheme
== nullptr)
242 if (mbIsLayoutPending
)
244 PaintBackground(rEvent
.UpdateRect
);
245 PaintChildren(rEvent
);
247 catch (RuntimeException
&)
249 OSL_FAIL("paint failed!");
253 //----- XMouseListener --------------------------------------------------------
255 void SAL_CALL
PresenterWindowManager::mousePressed (const css::awt::MouseEvent
&)
257 if (!mbIsSlideSorterActive
) // tdf#127921
258 mbIsMouseClickPending
= true;
261 void SAL_CALL
PresenterWindowManager::mouseReleased (const css::awt::MouseEvent
& rEvent
)
263 if (mbIsMouseClickPending
)
265 mbIsMouseClickPending
= false;
266 mpPresenterController
->HandleMouseClick(rEvent
);
270 void SAL_CALL
PresenterWindowManager::mouseEntered (const css::awt::MouseEvent
&)
272 mbIsMouseClickPending
= false;
275 void SAL_CALL
PresenterWindowManager::mouseExited (const css::awt::MouseEvent
&)
277 mbIsMouseClickPending
= false;
280 //----- XFocusListener --------------------------------------------------------
282 void SAL_CALL
PresenterWindowManager::focusGained (const css::awt::FocusEvent
& /*rEvent*/)
287 void SAL_CALL
PresenterWindowManager::focusLost (const css::awt::FocusEvent
&)
292 //----- XEventListener --------------------------------------------------------
294 void SAL_CALL
PresenterWindowManager::disposing (const lang::EventObject
& rEvent
)
296 if (rEvent
.Source
== mxParentWindow
)
297 mxParentWindow
= nullptr;
301 void PresenterWindowManager::PaintChildren (const awt::PaintEvent
& rEvent
) const
303 // Call windowPaint on all children that lie in or touch the
305 for (const auto& rxPane
: mpPaneContainer
->maPanes
)
309 // Make sure that the pane shall and can be painted.
310 if ( ! rxPane
->mbIsActive
)
312 if (rxPane
->mbIsSprite
)
314 if ( ! rxPane
->mxPane
.is())
316 if ( ! rxPane
->mxBorderWindow
.is())
318 Reference
<awt::XWindow
> xBorderWindow (rxPane
->mxBorderWindow
);
319 if ( ! xBorderWindow
.is())
322 // Get the area in which the border of the pane has to be painted.
323 const awt::Rectangle
aBorderBox (xBorderWindow
->getPosSize());
324 const awt::Rectangle
aBorderUpdateBox(
325 PresenterGeometryHelper::Intersection(
328 if (aBorderUpdateBox
.Width
<=0 || aBorderUpdateBox
.Height
<=0)
331 const awt::Rectangle
aLocalBorderUpdateBox(
332 PresenterGeometryHelper::TranslateRectangle(
337 // Invalidate the area of the content window.
338 mpPresenterController
->GetPaintManager()->Invalidate(
340 aLocalBorderUpdateBox
,
341 sal_Int16(awt::InvalidateStyle::CHILDREN
342 | awt::InvalidateStyle::NOTRANSPARENT
));
344 catch (RuntimeException
&)
346 OSL_FAIL("paint children failed!");
351 void PresenterWindowManager::SetLayoutMode (const LayoutMode eMode
)
353 OSL_ASSERT(mpPresenterController
);
355 if (meLayoutMode
== eMode
356 && !mbIsSlideSorterActive
357 && !mbIsHelpViewActive
)
360 meLayoutMode
= eMode
;
361 mbIsSlideSorterActive
= false;
362 mbIsHelpViewActive
= false;
364 mpPresenterController
->RequestViews(
365 mbIsSlideSorterActive
,
366 meLayoutMode
==LM_Notes
,
369 NotifyLayoutModeChange();
372 void PresenterWindowManager::SetSlideSorterState (bool bIsActive
)
374 if (mbIsSlideSorterActive
== bIsActive
)
377 mbIsSlideSorterActive
= bIsActive
;
378 if (mbIsSlideSorterActive
)
379 mbIsHelpViewActive
= false;
380 StoreViewMode(GetViewMode());
382 mpPresenterController
->RequestViews(
383 mbIsSlideSorterActive
,
384 meLayoutMode
==LM_Notes
,
387 NotifyLayoutModeChange();
390 void PresenterWindowManager::SetHelpViewState (bool bIsActive
)
392 if (mbIsHelpViewActive
== bIsActive
)
395 mbIsHelpViewActive
= bIsActive
;
396 if (mbIsHelpViewActive
)
397 mbIsSlideSorterActive
= false;
398 StoreViewMode(GetViewMode());
400 mpPresenterController
->RequestViews(
401 mbIsSlideSorterActive
,
402 meLayoutMode
==LM_Notes
,
405 NotifyLayoutModeChange();
408 void PresenterWindowManager::SetPauseState (bool bIsPaused
)
410 if (mbisPaused
== bIsPaused
)
413 mbisPaused
= bIsPaused
;
415 NotifyLayoutModeChange();
418 void PresenterWindowManager::SetViewMode (const ViewMode eMode
)
423 SetSlideSorterState(false);
424 SetHelpViewState(false);
425 SetLayoutMode(LM_Standard
);
429 SetSlideSorterState(false);
430 SetHelpViewState(false);
431 SetLayoutMode(LM_Notes
);
434 case VM_SlideOverview
:
435 SetHelpViewState(false);
436 SetSlideSorterState(true);
440 SetHelpViewState(true);
441 SetSlideSorterState(false);
445 StoreViewMode(eMode
);
448 PresenterWindowManager::ViewMode
PresenterWindowManager::GetViewMode() const
450 if (mbIsHelpViewActive
)
452 else if (mbIsSlideSorterActive
)
453 return VM_SlideOverview
;
454 else if (meLayoutMode
== LM_Notes
)
460 void PresenterWindowManager::RestoreViewMode()
463 PresenterConfigurationAccess
aConfiguration (
465 "/org.openoffice.Office.PresenterScreen/",
466 PresenterConfigurationAccess::READ_ONLY
);
467 aConfiguration
.GetConfigurationNode("Presenter/InitialViewMode") >>= nMode
;
472 SetViewMode(VM_Standard
);
476 SetViewMode(VM_Notes
);
480 SetViewMode(VM_SlideOverview
);
485 void PresenterWindowManager::StoreViewMode (const ViewMode eViewMode
)
489 PresenterConfigurationAccess
aConfiguration (
491 "/org.openoffice.Office.PresenterScreen/",
492 PresenterConfigurationAccess::READ_WRITE
);
493 aConfiguration
.GoToChild("Presenter");
499 aValue
<<= sal_Int32(0);
503 aValue
<<= sal_Int32(1);
506 case VM_SlideOverview
:
507 aValue
<<= sal_Int32(2);
511 aConfiguration
.SetProperty ("InitialViewMode", aValue
);
512 aConfiguration
.CommitChanges();
519 void PresenterWindowManager::AddLayoutListener (
520 const Reference
<document::XEventListener
>& rxListener
)
522 maLayoutListeners
.push_back(rxListener
);
525 void PresenterWindowManager::RemoveLayoutListener (
526 const Reference
<document::XEventListener
>& rxListener
)
528 // Assume that there are no multiple entries.
529 auto iListener
= std::find(maLayoutListeners
.begin(), maLayoutListeners
.end(), rxListener
);
530 if (iListener
!= maLayoutListeners
.end())
531 maLayoutListeners
.erase(iListener
);
534 void PresenterWindowManager::Layout()
536 if (!mxParentWindow
.is() || mbIsLayouting
)
539 mbIsLayoutPending
= false;
540 mbIsLayouting
= true;
541 mxScaledBackgroundBitmap
= nullptr;
542 mxClipPolygon
= nullptr;
546 if (mbIsSlideSorterActive
)
547 LayoutSlideSorterMode();
548 else if (mbIsHelpViewActive
)
551 switch (meLayoutMode
)
555 LayoutStandardMode();
569 mbIsLayouting
= false;
572 void PresenterWindowManager::LayoutStandardMode()
574 awt::Rectangle aBox
= mxParentWindow
->getPosSize();
576 const double nGoldenRatio ((1 + sqrt(5.0)) / 2);
577 const double nGap (20);
578 const double nHorizontalSlideDivide (aBox
.Width
/ nGoldenRatio
);
579 double nSlidePreviewTop (0);
582 // For the current slide view calculate the outer height from the outer
583 // width. This takes into account the slide aspect ratio and thus has to
584 // go over the inner pane size.
585 PresenterPaneContainer::SharedPaneDescriptor
pPane (
586 mpPaneContainer
->FindPaneURL(PresenterPaneFactory::msCurrentSlidePreviewPaneURL
));
589 const awt::Size
aCurrentSlideOuterBox(CalculatePaneSize(
590 nHorizontalSlideDivide
- 1.5*nGap
,
591 PresenterPaneFactory::msCurrentSlidePreviewPaneURL
));
592 nSlidePreviewTop
= (aBox
.Height
- aCurrentSlideOuterBox
.Height
) / 2;
594 /// check whether RTL interface or not
595 if(AllSettings::GetLayoutRTL())
596 Temp
=aBox
.Width
- aCurrentSlideOuterBox
.Width
- nGap
;
597 SetPanePosSizeAbsolute (
598 PresenterPaneFactory::msCurrentSlidePreviewPaneURL
,
601 aCurrentSlideOuterBox
.Width
,
602 aCurrentSlideOuterBox
.Height
);
605 // For the next slide view calculate the outer height from the outer
606 // width. This takes into account the slide aspect ratio and thus has to
607 // go over the inner pane size.
608 pPane
= mpPaneContainer
->FindPaneURL(PresenterPaneFactory::msNextSlidePreviewPaneURL
);
611 const awt::Size
aNextSlideOuterBox (CalculatePaneSize(
612 aBox
.Width
- nHorizontalSlideDivide
- 1.5*nGap
,
613 PresenterPaneFactory::msNextSlidePreviewPaneURL
));
614 double Temp
=aBox
.Width
- aNextSlideOuterBox
.Width
- nGap
;
615 /// check whether RTL interface or not
616 if(AllSettings::GetLayoutRTL())
618 SetPanePosSizeAbsolute (
619 PresenterPaneFactory::msNextSlidePreviewPaneURL
,
622 aNextSlideOuterBox
.Width
,
623 aNextSlideOuterBox
.Height
);
629 void PresenterWindowManager::LayoutNotesMode()
631 awt::Rectangle aBox
= mxParentWindow
->getPosSize();
633 const geometry::RealRectangle2D
aToolBarBox (LayoutToolBar());
635 const double nGoldenRatio ((1 + sqrt(5.0)) / 2);
636 const double nGap (20);
637 const double nPrimaryWidth (aBox
.Width
/ nGoldenRatio
);
638 const double nSecondaryWidth (aBox
.Width
- nPrimaryWidth
);
639 const double nTertiaryWidth (nSecondaryWidth
/ nGoldenRatio
);
640 double nSlidePreviewTop (0);
641 double nNotesViewBottom (aToolBarBox
.Y1
- nGap
);
642 /// check whether RTL interface or not
645 // The notes view has no fixed aspect ratio.
646 PresenterPaneContainer::SharedPaneDescriptor
pPane (
647 mpPaneContainer
->FindPaneURL(PresenterPaneFactory::msNotesPaneURL
));
650 const geometry::RealSize2D
aNotesViewOuterSize(
651 nPrimaryWidth
- 1.5*nGap
+ 0.5,
653 nSlidePreviewTop
= (aBox
.Height
654 - aToolBarBox
.Y2
+ aToolBarBox
.Y1
- aNotesViewOuterSize
.Height
) / 2;
655 /// check whether RTL interface or not
656 double Temp
=aBox
.Width
- aNotesViewOuterSize
.Width
- nGap
;
657 if(AllSettings::GetLayoutRTL())
659 SetPanePosSizeAbsolute (
660 PresenterPaneFactory::msNotesPaneURL
,
663 aNotesViewOuterSize
.Width
,
664 aNotesViewOuterSize
.Height
);
665 nNotesViewBottom
= nSlidePreviewTop
+ aNotesViewOuterSize
.Height
;
668 // For the current slide view calculate the outer height from the outer
669 // width. This takes into account the slide aspect ratio and thus has to
670 // go over the inner pane size.
671 pPane
= mpPaneContainer
->FindPaneURL(PresenterPaneFactory::msCurrentSlidePreviewPaneURL
);
674 const awt::Size
aCurrentSlideOuterBox(CalculatePaneSize(
675 nSecondaryWidth
- 1.5*nGap
,
676 PresenterPaneFactory::msCurrentSlidePreviewPaneURL
));
677 /// check whether RTL interface or not
679 if(AllSettings::GetLayoutRTL())
680 Temp
=aBox
.Width
- aCurrentSlideOuterBox
.Width
- nGap
;
681 SetPanePosSizeAbsolute (
682 PresenterPaneFactory::msCurrentSlidePreviewPaneURL
,
685 aCurrentSlideOuterBox
.Width
,
686 aCurrentSlideOuterBox
.Height
);
689 // For the next slide view calculate the outer height from the outer
690 // width. This takes into account the slide aspect ratio and thus has to
691 // go over the inner pane size.
692 pPane
= mpPaneContainer
->FindPaneURL(PresenterPaneFactory::msNextSlidePreviewPaneURL
);
696 const awt::Size
aNextSlideOuterBox (CalculatePaneSize(
698 PresenterPaneFactory::msNextSlidePreviewPaneURL
));
699 /// check whether RTL interface or not
701 if(AllSettings::GetLayoutRTL())
702 Temp
=aBox
.Width
- aNextSlideOuterBox
.Width
- nGap
;
703 SetPanePosSizeAbsolute (
704 PresenterPaneFactory::msNextSlidePreviewPaneURL
,
706 nNotesViewBottom
- aNextSlideOuterBox
.Height
,
707 aNextSlideOuterBox
.Width
,
708 aNextSlideOuterBox
.Height
);
713 void PresenterWindowManager::LayoutSlideSorterMode()
715 const geometry::RealRectangle2D
aToolBarBox (LayoutToolBar());
717 awt::Rectangle aWindowBox
= mxParentWindow
->getPosSize();
718 const double nGap (20);
719 SetPanePosSizeAbsolute(
720 mpPaneContainer
->GetPaneURLForViewURL(PresenterViewFactory::msSlideSorterURL
),
723 aWindowBox
.Width
- 2*nGap
,
724 aToolBarBox
.Y1
- 2*nGap
);
727 void PresenterWindowManager::LayoutHelpMode()
729 const geometry::RealRectangle2D
aToolBarBox (LayoutToolBar());
731 awt::Rectangle aWindowBox
= mxParentWindow
->getPosSize();
732 const double nGap (20);
733 const double nGoldenRatio ((1 + sqrt(5.0)) / 2);
734 const double nWidth
= ::std::min(aWindowBox
.Width
- 2*nGap
, aWindowBox
.Width
/nGoldenRatio
);
735 SetPanePosSizeAbsolute(
736 mpPaneContainer
->GetPaneURLForViewURL(PresenterViewFactory::msHelpViewURL
),
737 (aWindowBox
.Width
- nWidth
)/2,
740 aToolBarBox
.Y1
- 2*nGap
);
743 geometry::RealRectangle2D
PresenterWindowManager::LayoutToolBar()
745 double nToolBarWidth (400);
746 double nToolBarHeight (80);
748 // Get access to the tool bar.
749 PresenterPaneContainer::SharedPaneDescriptor
pDescriptor(
750 mpPaneContainer
->FindPaneURL(PresenterPaneFactory::msToolBarPaneURL
));
753 PresenterToolBarView
* pToolBarView
754 = dynamic_cast<PresenterToolBarView
*>(pDescriptor
->mxView
.get());
755 if (pToolBarView
!= nullptr && pToolBarView
->GetPresenterToolBar().is())
757 geometry::RealSize2D
aSize (pToolBarView
->GetPresenterToolBar()->GetMinimalSize());
759 if (mpPaneBorderPainter
.is())
761 const awt::Rectangle
aBox (mpPaneBorderPainter
->addBorder (
762 PresenterPaneFactory::msToolBarPaneURL
,
766 PresenterGeometryHelper::Round(aSize
.Width
),
767 PresenterGeometryHelper::Round(aSize
.Height
)),
768 css::drawing::framework::BorderType_TOTAL_BORDER
));
770 nToolBarWidth
= aBox
.Width
;
771 nToolBarHeight
= aBox
.Height
;
775 nToolBarWidth
= aSize
.Width
+ 20;
776 nToolBarHeight
= aSize
.Height
+ 10;
781 const awt::Rectangle aBox
= mxParentWindow
->getPosSize();
782 const double nToolBarX ((aBox
.Width
- nToolBarWidth
) / 2);
783 const double nToolBarY (aBox
.Height
- nToolBarHeight
);
784 SetPanePosSizeAbsolute(
785 PresenterPaneFactory::msToolBarPaneURL
,
791 return geometry::RealRectangle2D(
794 nToolBarX
+ nToolBarWidth
- 1,
795 nToolBarY
+ nToolBarHeight
- 1);
798 awt::Size
PresenterWindowManager::CalculatePaneSize (
799 const double nOuterWidth
,
800 const OUString
& rsPaneURL
)
802 // Calculate the inner width by removing the pane border.
803 awt::Rectangle
aInnerBox (mpPaneBorderPainter
->RemoveBorder (
806 sal_Int32(nOuterWidth
+0.5),sal_Int32(nOuterWidth
)),
807 drawing::framework::BorderType_TOTAL_BORDER
));
809 // Calculate the inner height with the help of the slide aspect ratio.
810 const double nCurrentSlideInnerHeight (
811 aInnerBox
.Width
/ mpPresenterController
->GetSlideAspectRatio());
813 // Add the pane border to get the outer box.
814 awt::Rectangle
aOuterBox (mpPaneBorderPainter
->AddBorder (
817 aInnerBox
.Width
,sal_Int32(nCurrentSlideInnerHeight
+0.5)),
818 drawing::framework::BorderType_TOTAL_BORDER
));
820 return awt::Size(aOuterBox
.Width
, aOuterBox
.Height
);
823 void PresenterWindowManager::NotifyLayoutModeChange()
825 document::EventObject aEvent
;
826 aEvent
.Source
= Reference
<XInterface
>(static_cast<XWeak
*>(this));
828 LayoutListenerContainer
aContainerCopy (maLayoutListeners
);
829 for (const auto& rxListener
: aContainerCopy
)
835 rxListener
->notifyEvent(aEvent
);
837 catch (lang::DisposedException
&)
839 RemoveLayoutListener(rxListener
);
841 catch (RuntimeException
&)
848 void PresenterWindowManager::NotifyDisposing()
850 lang::EventObject aEvent
;
851 aEvent
.Source
= static_cast<XWeak
*>(this);
853 LayoutListenerContainer aContainer
;
854 aContainer
.swap(maLayoutListeners
);
855 for (auto& rxListener
: aContainer
)
861 rxListener
->disposing(aEvent
);
863 catch (lang::DisposedException
&)
866 catch (RuntimeException
&)
873 void PresenterWindowManager::UpdateWindowSize (const Reference
<awt::XWindow
>& rxBorderWindow
)
875 PresenterPaneContainer::SharedPaneDescriptor
pDescriptor (
876 mpPaneContainer
->FindBorderWindow(rxBorderWindow
));
879 mxClipPolygon
= nullptr;
881 // ToTop is called last because it may invalidate the iterator.
882 if ( ! mbIsLayouting
)
883 mpPaneContainer
->ToTop(pDescriptor
);
887 void PresenterWindowManager::PaintBackground (const awt::Rectangle
& rUpdateBox
)
889 if ( ! mxParentWindow
.is())
892 Reference
<rendering::XGraphicDevice
> xDevice (mxParentCanvas
->getDevice());
896 // Create a polygon for the background and for clipping.
897 Reference
<rendering::XPolyPolygon2D
> xBackgroundPolygon (
898 PresenterGeometryHelper::CreatePolygon(mxParentWindow
->getPosSize(), xDevice
));
899 if ( ! mxClipPolygon
.is())
900 mxClipPolygon
= CreateClipPolyPolygon();
902 // Create View- and RenderState structs.
903 const rendering::ViewState
aViewState(
904 geometry::AffineMatrix2D(1,0,0, 0,1,0),
905 PresenterGeometryHelper::CreatePolygon(rUpdateBox
, xDevice
));
906 rendering::RenderState
aRenderState (
907 geometry::AffineMatrix2D(1,0,0, 0,1,0),
910 rendering::CompositeOperation::SOURCE
);
912 // Paint the background.
913 if (!mpBackgroundBitmap
)
916 ProvideBackgroundBitmap();
918 if (mxScaledBackgroundBitmap
.is())
920 const geometry::IntegerSize2D
aBitmapSize(mxScaledBackgroundBitmap
->getSize());
921 Sequence
<rendering::Texture
> aTextures
924 geometry::AffineMatrix2D( aBitmapSize
.Width
,0,0, 0,aBitmapSize
.Height
,0),
927 mxScaledBackgroundBitmap
,
930 rendering::StrokeAttributes(),
931 rendering::TexturingMode::REPEAT
,
932 rendering::TexturingMode::REPEAT
936 mxParentCanvas
->fillTexturedPolyPolygon(
944 const util::Color
aBackgroundColor (mpBackgroundBitmap
->maReplacementColor
);
945 auto pDeviceColor
= aRenderState
.DeviceColor
.getArray();
946 pDeviceColor
[0] = ((aBackgroundColor
>> 16) & 0x0ff) / 255.0;
947 pDeviceColor
[1] = ((aBackgroundColor
>> 8) & 0x0ff) / 255.0;
948 pDeviceColor
[2] = ((aBackgroundColor
>> 0) & 0x0ff) / 255.0;
949 pDeviceColor
[3] = ((aBackgroundColor
>> 24) & 0x0ff) / 255.0;
950 mxParentCanvas
->fillPolyPolygon(
957 void PresenterWindowManager::ProvideBackgroundBitmap()
959 if ( mxScaledBackgroundBitmap
.is())
962 Reference
<rendering::XBitmap
> xBitmap (mpBackgroundBitmap
->GetNormalBitmap());
966 const bool bStretchVertical (mpBackgroundBitmap
->meVerticalTexturingMode
967 == PresenterBitmapDescriptor::Stretch
);
968 const bool bStretchHorizontal (mpBackgroundBitmap
->meHorizontalTexturingMode
969 == PresenterBitmapDescriptor::Stretch
);
970 if (bStretchHorizontal
|| bStretchVertical
)
972 geometry::RealSize2D aSize
;
973 if (bStretchVertical
)
974 aSize
.Height
= mxParentWindow
->getPosSize().Height
;
976 aSize
.Height
= xBitmap
->getSize().Height
;
977 if (bStretchHorizontal
)
978 aSize
.Width
= mxParentWindow
->getPosSize().Width
;
980 aSize
.Width
= xBitmap
->getSize().Width
;
981 mxScaledBackgroundBitmap
= xBitmap
->getScaledBitmap(aSize
, false);
985 mxScaledBackgroundBitmap
= xBitmap
;
989 Reference
<rendering::XPolyPolygon2D
> PresenterWindowManager::CreateClipPolyPolygon() const
991 // Create a clip polygon that includes the whole update area but has the
992 // content windows as holes.
993 const sal_Int32
nPaneCount (mpPaneContainer
->maPanes
.size());
994 ::std::vector
<awt::Rectangle
> aRectangles
;
995 aRectangles
.reserve(1+nPaneCount
);
996 aRectangles
.push_back(mxParentWindow
->getPosSize());
997 for (const auto& pDescriptor
: mpPaneContainer
->maPanes
)
999 if ( ! pDescriptor
->mbIsActive
)
1001 if ( ! pDescriptor
->mbIsOpaque
)
1003 if ( ! pDescriptor
->mxBorderWindow
.is() || ! pDescriptor
->mxContentWindow
.is())
1005 Reference
<awt::XWindow2
> xWindow (pDescriptor
->mxBorderWindow
, UNO_QUERY
);
1006 if (xWindow
.is() && ! xWindow
->isVisible())
1009 const awt::Rectangle
aOuterBorderBox (pDescriptor
->mxBorderWindow
->getPosSize());
1010 awt::Rectangle
aInnerBorderBox (pDescriptor
->mxContentWindow
->getPosSize());
1011 aInnerBorderBox
.X
+= aOuterBorderBox
.X
;
1012 aInnerBorderBox
.Y
+= aOuterBorderBox
.Y
;
1013 aRectangles
.push_back(aInnerBorderBox
);
1015 Reference
<rendering::XPolyPolygon2D
> xPolyPolygon (
1016 PresenterGeometryHelper::CreatePolygon(
1018 mxParentCanvas
->getDevice()));
1019 if (xPolyPolygon
.is())
1020 xPolyPolygon
->setFillRule(rendering::FillRule_EVEN_ODD
);
1021 return xPolyPolygon
;
1024 void PresenterWindowManager::Update()
1026 mxClipPolygon
= nullptr;
1027 mbIsLayoutPending
= true;
1029 mpPresenterController
->GetPaintManager()->Invalidate(mxParentWindow
);
1032 void PresenterWindowManager::ThrowIfDisposed() const
1034 if (rBHelper
.bDisposed
|| rBHelper
.bInDispose
)
1036 throw lang::DisposedException (
1037 "PresenterWindowManager has already been disposed",
1038 const_cast<uno::XWeak
*>(static_cast<const uno::XWeak
*>(this)));
1042 } // end of namespace ::sdext::presenter
1044 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */