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 .
20 #include <vcl/settings.hxx>
21 #include "PresenterWindowManager.hxx"
22 #include "PresenterController.hxx"
23 #include "PresenterGeometryHelper.hxx"
24 #include "PresenterPaintManager.hxx"
25 #include "PresenterPaneBorderPainter.hxx"
26 #include "PresenterPaneContainer.hxx"
27 #include "PresenterPaneFactory.hxx"
28 #include "PresenterToolBar.hxx"
29 #include "PresenterViewFactory.hxx"
30 #include "PresenterTheme.hxx"
31 #include <com/sun/star/awt/InvalidateStyle.hpp>
32 #include <com/sun/star/awt/PosSize.hpp>
33 #include <com/sun/star/awt/XWindow2.hpp>
34 #include <com/sun/star/awt/XWindowPeer.hpp>
35 #include <com/sun/star/rendering/CompositeOperation.hpp>
36 #include <com/sun/star/rendering/FillRule.hpp>
37 #include <com/sun/star/rendering/Texture.hpp>
38 #include <com/sun/star/rendering/TexturingMode.hpp>
41 using namespace ::com::sun::star
;
42 using namespace ::com::sun::star::uno
;
43 using namespace ::com::sun::star::drawing::framework
;
45 namespace sdext::presenter
{
47 //===== PresenterWindowManager ================================================
49 PresenterWindowManager::PresenterWindowManager (
50 const Reference
<XComponentContext
>& rxContext
,
51 const ::rtl::Reference
<PresenterPaneContainer
>& rpPaneContainer
,
52 const ::rtl::Reference
<PresenterController
>& rpPresenterController
)
53 : PresenterWindowManagerInterfaceBase(m_aMutex
),
54 mxComponentContext(rxContext
),
55 mpPresenterController(rpPresenterController
),
58 mxPaneBorderManager(),
59 mpPaneBorderPainter(),
60 mpPaneContainer(rpPaneContainer
),
61 mbIsLayoutPending(true),
65 mxScaledBackgroundBitmap(),
67 meLayoutMode(LM_Generic
),
68 mbIsSlideSorterActive(false),
69 mbIsHelpViewActive(false),
72 mbIsMouseClickPending(false)
77 PresenterWindowManager::~PresenterWindowManager()
81 void SAL_CALL
PresenterWindowManager::disposing()
85 SetParentPane(nullptr);
87 Reference
<lang::XComponent
> xComponent (mxPaneBorderManager
, UNO_QUERY
);
89 xComponent
->dispose();
90 mxPaneBorderManager
= nullptr;
92 for (const auto& rxPane
: mpPaneContainer
->maPanes
)
94 if (rxPane
->mxBorderWindow
.is())
96 rxPane
->mxBorderWindow
->removeWindowListener(this);
97 rxPane
->mxBorderWindow
->removeFocusListener(this);
98 rxPane
->mxBorderWindow
->removeMouseListener(this);
103 void PresenterWindowManager::SetParentPane (
104 const Reference
<drawing::framework::XPane
>& rxPane
)
106 if (mxParentWindow
.is())
108 mxParentWindow
->removeWindowListener(this);
109 mxParentWindow
->removePaintListener(this);
110 mxParentWindow
->removeMouseListener(this);
111 mxParentWindow
->removeFocusListener(this);
113 mxParentWindow
= nullptr;
114 mxParentCanvas
= nullptr;
118 mxParentWindow
= rxPane
->getWindow();
119 mxParentCanvas
= rxPane
->getCanvas();
123 mxParentWindow
= nullptr;
126 if (mxParentWindow
.is())
128 mxParentWindow
->addWindowListener(this);
129 mxParentWindow
->addPaintListener(this);
130 mxParentWindow
->addMouseListener(this);
131 mxParentWindow
->addFocusListener(this);
133 // We paint our own background, make that of the parent window transparent.
134 Reference
<awt::XWindowPeer
> xPeer (mxParentWindow
, UNO_QUERY
);
136 xPeer
->setBackground(util::Color(0xff000000));
140 void PresenterWindowManager::SetTheme (const std::shared_ptr
<PresenterTheme
>& rpTheme
)
144 // Get background bitmap or background color from the theme.
146 if (mpTheme
!= nullptr)
148 mpBackgroundBitmap
= mpTheme
->GetBitmap(OUString(), "Background");
152 void PresenterWindowManager::NotifyViewCreation (const Reference
<XView
>& rxView
)
154 PresenterPaneContainer::SharedPaneDescriptor
pDescriptor (
155 mpPaneContainer
->FindPaneId(rxView
->getResourceId()->getAnchor()));
156 OSL_ASSERT(pDescriptor
);
161 mpPresenterController
->GetPaintManager()->Invalidate(
162 pDescriptor
->mxContentWindow
,
163 sal_Int16(awt::InvalidateStyle::TRANSPARENT
164 | awt::InvalidateStyle::CHILDREN
));
168 void PresenterWindowManager::SetPanePosSizeAbsolute (
169 const OUString
& rsPaneURL
,
173 const double nHeight
)
175 PresenterPaneContainer::SharedPaneDescriptor
pDescriptor (
176 mpPaneContainer
->FindPaneURL(rsPaneURL
));
179 if (pDescriptor
->mxBorderWindow
.is())
180 pDescriptor
->mxBorderWindow
->setPosSize(
181 ::sal::static_int_cast
<sal_Int32
>(nX
),
182 ::sal::static_int_cast
<sal_Int32
>(nY
),
183 ::sal::static_int_cast
<sal_Int32
>(nWidth
),
184 ::sal::static_int_cast
<sal_Int32
>(nHeight
),
185 awt::PosSize::POSSIZE
);
189 void PresenterWindowManager::SetPaneBorderPainter (
190 const ::rtl::Reference
<PresenterPaneBorderPainter
>& rPainter
)
192 mpPaneBorderPainter
= rPainter
;
195 //----- XWindowListener -------------------------------------------------------
197 void SAL_CALL
PresenterWindowManager::windowResized (const awt::WindowEvent
& rEvent
)
200 if (rEvent
.Source
== mxParentWindow
)
206 Reference
<awt::XWindow
> xWindow (rEvent
.Source
,UNO_QUERY
);
209 UpdateWindowSize(xWindow
);
211 // Make sure the background of a transparent window is painted.
212 mpPresenterController
->GetPaintManager()->Invalidate(mxParentWindow
);
217 void SAL_CALL
PresenterWindowManager::windowMoved (const awt::WindowEvent
& rEvent
)
220 if (rEvent
.Source
!= mxParentWindow
)
222 Reference
<awt::XWindow
> xWindow (rEvent
.Source
,UNO_QUERY
);
223 UpdateWindowSize(xWindow
);
225 // Make sure the background of a transparent window is painted.
226 mpPresenterController
->GetPaintManager()->Invalidate(xWindow
);
230 void SAL_CALL
PresenterWindowManager::windowShown (const lang::EventObject
&) {}
232 void SAL_CALL
PresenterWindowManager::windowHidden (const lang::EventObject
&) {}
234 //----- XPaintListener --------------------------------------------------------
236 void SAL_CALL
PresenterWindowManager::windowPaint (const awt::PaintEvent
& rEvent
)
240 if ( ! mxParentWindow
.is())
242 if ( ! mxParentCanvas
.is())
245 if (mpTheme
== nullptr)
250 if (mbIsLayoutPending
)
252 PaintBackground(rEvent
.UpdateRect
);
253 PaintChildren(rEvent
);
255 catch (RuntimeException
&)
257 OSL_FAIL("paint failed!");
261 //----- XMouseListener --------------------------------------------------------
263 void SAL_CALL
PresenterWindowManager::mousePressed (const css::awt::MouseEvent
&)
265 if (!mbIsSlideSorterActive
) // tdf#127921
266 mbIsMouseClickPending
= true;
269 void SAL_CALL
PresenterWindowManager::mouseReleased (const css::awt::MouseEvent
& rEvent
)
271 if (mbIsMouseClickPending
)
273 mbIsMouseClickPending
= false;
274 mpPresenterController
->HandleMouseClick(rEvent
);
278 void SAL_CALL
PresenterWindowManager::mouseEntered (const css::awt::MouseEvent
&)
280 mbIsMouseClickPending
= false;
283 void SAL_CALL
PresenterWindowManager::mouseExited (const css::awt::MouseEvent
&)
285 mbIsMouseClickPending
= false;
288 //----- XFocusListener --------------------------------------------------------
290 void SAL_CALL
PresenterWindowManager::focusGained (const css::awt::FocusEvent
& /*rEvent*/)
295 void SAL_CALL
PresenterWindowManager::focusLost (const css::awt::FocusEvent
&)
300 //----- XEventListener --------------------------------------------------------
302 void SAL_CALL
PresenterWindowManager::disposing (const lang::EventObject
& rEvent
)
304 if (rEvent
.Source
== mxParentWindow
)
305 mxParentWindow
= nullptr;
309 void PresenterWindowManager::PaintChildren (const awt::PaintEvent
& rEvent
) const
311 // Call windowPaint on all children that lie in or touch the
313 for (const auto& rxPane
: mpPaneContainer
->maPanes
)
317 // Make sure that the pane shall and can be painted.
318 if ( ! rxPane
->mbIsActive
)
320 if (rxPane
->mbIsSprite
)
322 if ( ! rxPane
->mxPane
.is())
324 if ( ! rxPane
->mxBorderWindow
.is())
326 Reference
<awt::XWindow
> xBorderWindow (rxPane
->mxBorderWindow
);
327 if ( ! xBorderWindow
.is())
330 // Get the area in which the border of the pane has to be painted.
331 const awt::Rectangle
aBorderBox (xBorderWindow
->getPosSize());
332 const awt::Rectangle
aBorderUpdateBox(
333 PresenterGeometryHelper::Intersection(
336 if (aBorderUpdateBox
.Width
<=0 || aBorderUpdateBox
.Height
<=0)
339 const awt::Rectangle
aLocalBorderUpdateBox(
340 PresenterGeometryHelper::TranslateRectangle(
345 // Invalidate the area of the content window.
346 mpPresenterController
->GetPaintManager()->Invalidate(
348 aLocalBorderUpdateBox
,
349 sal_Int16(awt::InvalidateStyle::CHILDREN
350 | awt::InvalidateStyle::NOTRANSPARENT
));
352 catch (RuntimeException
&)
354 OSL_FAIL("paint children failed!");
359 void PresenterWindowManager::SetLayoutMode (const LayoutMode eMode
)
361 OSL_ASSERT(mpPresenterController
);
363 if (meLayoutMode
== eMode
364 && !mbIsSlideSorterActive
365 && !mbIsHelpViewActive
)
368 meLayoutMode
= eMode
;
369 mbIsSlideSorterActive
= false;
370 mbIsHelpViewActive
= false;
372 mpPresenterController
->RequestViews(
373 mbIsSlideSorterActive
,
374 meLayoutMode
==LM_Notes
,
377 NotifyLayoutModeChange();
380 void PresenterWindowManager::SetSlideSorterState (bool bIsActive
)
382 if (mbIsSlideSorterActive
== bIsActive
)
385 mbIsSlideSorterActive
= bIsActive
;
386 if (mbIsSlideSorterActive
)
387 mbIsHelpViewActive
= false;
388 StoreViewMode(GetViewMode());
390 mpPresenterController
->RequestViews(
391 mbIsSlideSorterActive
,
392 meLayoutMode
==LM_Notes
,
395 NotifyLayoutModeChange();
398 void PresenterWindowManager::SetHelpViewState (bool bIsActive
)
400 if (mbIsHelpViewActive
== bIsActive
)
403 mbIsHelpViewActive
= bIsActive
;
404 if (mbIsHelpViewActive
)
405 mbIsSlideSorterActive
= false;
406 StoreViewMode(GetViewMode());
408 mpPresenterController
->RequestViews(
409 mbIsSlideSorterActive
,
410 meLayoutMode
==LM_Notes
,
413 NotifyLayoutModeChange();
416 void PresenterWindowManager::SetPauseState (bool bIsPaused
)
418 if (mbisPaused
== bIsPaused
)
421 mbisPaused
= bIsPaused
;
423 NotifyLayoutModeChange();
426 void PresenterWindowManager::SetViewMode (const ViewMode eMode
)
431 SetSlideSorterState(false);
432 SetHelpViewState(false);
433 SetLayoutMode(LM_Standard
);
437 SetSlideSorterState(false);
438 SetHelpViewState(false);
439 SetLayoutMode(LM_Notes
);
442 case VM_SlideOverview
:
443 SetHelpViewState(false);
444 SetSlideSorterState(true);
448 SetHelpViewState(true);
449 SetSlideSorterState(false);
453 StoreViewMode(eMode
);
456 PresenterWindowManager::ViewMode
PresenterWindowManager::GetViewMode() const
458 if (mbIsHelpViewActive
)
460 else if (mbIsSlideSorterActive
)
461 return VM_SlideOverview
;
462 else if (meLayoutMode
== LM_Notes
)
468 void PresenterWindowManager::RestoreViewMode()
471 PresenterConfigurationAccess
aConfiguration (
473 "/org.openoffice.Office.PresenterScreen/",
474 PresenterConfigurationAccess::READ_ONLY
);
475 aConfiguration
.GetConfigurationNode("Presenter/InitialViewMode") >>= nMode
;
480 SetViewMode(VM_Standard
);
484 SetViewMode(VM_Notes
);
488 SetViewMode(VM_SlideOverview
);
493 void PresenterWindowManager::StoreViewMode (const ViewMode eViewMode
)
497 PresenterConfigurationAccess
aConfiguration (
499 "/org.openoffice.Office.PresenterScreen/",
500 PresenterConfigurationAccess::READ_WRITE
);
501 aConfiguration
.GoToChild("Presenter");
507 aValue
<<= sal_Int32(0);
511 aValue
<<= sal_Int32(1);
514 case VM_SlideOverview
:
515 aValue
<<= sal_Int32(2);
519 aConfiguration
.SetProperty ("InitialViewMode", aValue
);
520 aConfiguration
.CommitChanges();
527 void PresenterWindowManager::AddLayoutListener (
528 const Reference
<document::XEventListener
>& rxListener
)
530 maLayoutListeners
.push_back(rxListener
);
533 void PresenterWindowManager::RemoveLayoutListener (
534 const Reference
<document::XEventListener
>& rxListener
)
536 // Assume that there are no multiple entries.
537 auto iListener
= std::find(maLayoutListeners
.begin(), maLayoutListeners
.end(), rxListener
);
538 if (iListener
!= maLayoutListeners
.end())
539 maLayoutListeners
.erase(iListener
);
542 void PresenterWindowManager::Layout()
544 if (!mxParentWindow
.is() || mbIsLayouting
)
547 mbIsLayoutPending
= false;
548 mbIsLayouting
= true;
549 mxScaledBackgroundBitmap
= nullptr;
550 mxClipPolygon
= nullptr;
554 if (mbIsSlideSorterActive
)
555 LayoutSlideSorterMode();
556 else if (mbIsHelpViewActive
)
559 switch (meLayoutMode
)
563 LayoutStandardMode();
577 mbIsLayouting
= false;
580 void PresenterWindowManager::LayoutStandardMode()
582 awt::Rectangle aBox
= mxParentWindow
->getPosSize();
584 const double nGoldenRatio ((1 + sqrt(5.0)) / 2);
585 const double nGap (20);
586 const double nHorizontalSlideDivide (aBox
.Width
/ nGoldenRatio
);
587 double nSlidePreviewTop (0);
590 // For the current slide view calculate the outer height from the outer
591 // width. This takes into account the slide aspect ratio and thus has to
592 // go over the inner pane size.
593 PresenterPaneContainer::SharedPaneDescriptor
pPane (
594 mpPaneContainer
->FindPaneURL(PresenterPaneFactory::msCurrentSlidePreviewPaneURL
));
597 const awt::Size
aCurrentSlideOuterBox(CalculatePaneSize(
598 nHorizontalSlideDivide
- 1.5*nGap
,
599 PresenterPaneFactory::msCurrentSlidePreviewPaneURL
));
600 nSlidePreviewTop
= (aBox
.Height
- aCurrentSlideOuterBox
.Height
) / 2;
602 /// check whether RTL interface or not
603 if(AllSettings::GetLayoutRTL())
604 Temp
=aBox
.Width
- aCurrentSlideOuterBox
.Width
- nGap
;
605 SetPanePosSizeAbsolute (
606 PresenterPaneFactory::msCurrentSlidePreviewPaneURL
,
609 aCurrentSlideOuterBox
.Width
,
610 aCurrentSlideOuterBox
.Height
);
613 // For the next slide view calculate the outer height from the outer
614 // width. This takes into account the slide aspect ratio and thus has to
615 // go over the inner pane size.
616 pPane
= mpPaneContainer
->FindPaneURL(PresenterPaneFactory::msNextSlidePreviewPaneURL
);
619 const awt::Size
aNextSlideOuterBox (CalculatePaneSize(
620 aBox
.Width
- nHorizontalSlideDivide
- 1.5*nGap
,
621 PresenterPaneFactory::msNextSlidePreviewPaneURL
));
622 double Temp
=aBox
.Width
- aNextSlideOuterBox
.Width
- nGap
;
623 /// check whether RTL interface or not
624 if(AllSettings::GetLayoutRTL())
626 SetPanePosSizeAbsolute (
627 PresenterPaneFactory::msNextSlidePreviewPaneURL
,
630 aNextSlideOuterBox
.Width
,
631 aNextSlideOuterBox
.Height
);
637 void PresenterWindowManager::LayoutNotesMode()
639 awt::Rectangle aBox
= mxParentWindow
->getPosSize();
641 const geometry::RealRectangle2D
aToolBarBox (LayoutToolBar());
643 const double nGoldenRatio ((1 + sqrt(5.0)) / 2);
644 const double nGap (20);
645 const double nPrimaryWidth (aBox
.Width
/ nGoldenRatio
);
646 const double nSecondaryWidth (aBox
.Width
- nPrimaryWidth
);
647 const double nTertiaryWidth (nSecondaryWidth
/ nGoldenRatio
);
648 double nSlidePreviewTop (0);
649 double nNotesViewBottom (aToolBarBox
.Y1
- nGap
);
650 /// check whether RTL interface or not
653 // The notes view has no fixed aspect ratio.
654 PresenterPaneContainer::SharedPaneDescriptor
pPane (
655 mpPaneContainer
->FindPaneURL(PresenterPaneFactory::msNotesPaneURL
));
658 const geometry::RealSize2D
aNotesViewOuterSize(
659 nPrimaryWidth
- 1.5*nGap
+ 0.5,
661 nSlidePreviewTop
= (aBox
.Height
662 - aToolBarBox
.Y2
+ aToolBarBox
.Y1
- aNotesViewOuterSize
.Height
) / 2;
663 /// check whether RTL interface or not
664 double Temp
=aBox
.Width
- aNotesViewOuterSize
.Width
- nGap
;
665 if(AllSettings::GetLayoutRTL())
667 SetPanePosSizeAbsolute (
668 PresenterPaneFactory::msNotesPaneURL
,
671 aNotesViewOuterSize
.Width
,
672 aNotesViewOuterSize
.Height
);
673 nNotesViewBottom
= nSlidePreviewTop
+ aNotesViewOuterSize
.Height
;
676 // For the current slide view calculate the outer height from the outer
677 // width. This takes into account the slide aspect ratio and thus has to
678 // go over the inner pane size.
679 pPane
= mpPaneContainer
->FindPaneURL(PresenterPaneFactory::msCurrentSlidePreviewPaneURL
);
682 const awt::Size
aCurrentSlideOuterBox(CalculatePaneSize(
683 nSecondaryWidth
- 1.5*nGap
,
684 PresenterPaneFactory::msCurrentSlidePreviewPaneURL
));
685 /// check whether RTL interface or not
687 if(AllSettings::GetLayoutRTL())
688 Temp
=aBox
.Width
- aCurrentSlideOuterBox
.Width
- nGap
;
689 SetPanePosSizeAbsolute (
690 PresenterPaneFactory::msCurrentSlidePreviewPaneURL
,
693 aCurrentSlideOuterBox
.Width
,
694 aCurrentSlideOuterBox
.Height
);
697 // For the next slide view calculate the outer height from the outer
698 // width. This takes into account the slide aspect ratio and thus has to
699 // go over the inner pane size.
700 pPane
= mpPaneContainer
->FindPaneURL(PresenterPaneFactory::msNextSlidePreviewPaneURL
);
704 const awt::Size
aNextSlideOuterBox (CalculatePaneSize(
706 PresenterPaneFactory::msNextSlidePreviewPaneURL
));
707 /// check whether RTL interface or not
709 if(AllSettings::GetLayoutRTL())
710 Temp
=aBox
.Width
- aNextSlideOuterBox
.Width
- nGap
;
711 SetPanePosSizeAbsolute (
712 PresenterPaneFactory::msNextSlidePreviewPaneURL
,
714 nNotesViewBottom
- aNextSlideOuterBox
.Height
,
715 aNextSlideOuterBox
.Width
,
716 aNextSlideOuterBox
.Height
);
721 void PresenterWindowManager::LayoutSlideSorterMode()
723 const geometry::RealRectangle2D
aToolBarBox (LayoutToolBar());
725 awt::Rectangle aWindowBox
= mxParentWindow
->getPosSize();
726 const double nGap (20);
727 SetPanePosSizeAbsolute(
728 mpPaneContainer
->GetPaneURLForViewURL(PresenterViewFactory::msSlideSorterURL
),
731 aWindowBox
.Width
- 2*nGap
,
732 aToolBarBox
.Y1
- 2*nGap
);
735 void PresenterWindowManager::LayoutHelpMode()
737 const geometry::RealRectangle2D
aToolBarBox (LayoutToolBar());
739 awt::Rectangle aWindowBox
= mxParentWindow
->getPosSize();
740 const double nGap (20);
741 const double nGoldenRatio ((1 + sqrt(5.0)) / 2);
742 const double nWidth
= ::std::min(aWindowBox
.Width
- 2*nGap
, aWindowBox
.Width
/nGoldenRatio
);
743 SetPanePosSizeAbsolute(
744 mpPaneContainer
->GetPaneURLForViewURL(PresenterViewFactory::msHelpViewURL
),
745 (aWindowBox
.Width
- nWidth
)/2,
748 aToolBarBox
.Y1
- 2*nGap
);
751 geometry::RealRectangle2D
PresenterWindowManager::LayoutToolBar()
753 double nToolBarWidth (400);
754 double nToolBarHeight (80);
756 // Get access to the tool bar.
757 PresenterPaneContainer::SharedPaneDescriptor
pDescriptor(
758 mpPaneContainer
->FindPaneURL(PresenterPaneFactory::msToolBarPaneURL
));
761 PresenterToolBarView
* pToolBarView
762 = dynamic_cast<PresenterToolBarView
*>(pDescriptor
->mxView
.get());
763 if (pToolBarView
!= nullptr && pToolBarView
->GetPresenterToolBar().is())
765 geometry::RealSize2D
aSize (pToolBarView
->GetPresenterToolBar()->GetMinimalSize());
767 if (mpPaneBorderPainter
.is())
769 const awt::Rectangle
aBox (mpPaneBorderPainter
->addBorder (
770 PresenterPaneFactory::msToolBarPaneURL
,
774 PresenterGeometryHelper::Round(aSize
.Width
),
775 PresenterGeometryHelper::Round(aSize
.Height
)),
776 css::drawing::framework::BorderType_TOTAL_BORDER
));
778 nToolBarWidth
= aBox
.Width
;
779 nToolBarHeight
= aBox
.Height
;
783 nToolBarWidth
= aSize
.Width
+ 20;
784 nToolBarHeight
= aSize
.Height
+ 10;
789 const awt::Rectangle aBox
= mxParentWindow
->getPosSize();
790 const double nToolBarX ((aBox
.Width
- nToolBarWidth
) / 2);
791 const double nToolBarY (aBox
.Height
- nToolBarHeight
);
792 SetPanePosSizeAbsolute(
793 PresenterPaneFactory::msToolBarPaneURL
,
799 return geometry::RealRectangle2D(
802 nToolBarX
+ nToolBarWidth
- 1,
803 nToolBarY
+ nToolBarHeight
- 1);
806 awt::Size
PresenterWindowManager::CalculatePaneSize (
807 const double nOuterWidth
,
808 const OUString
& rsPaneURL
)
810 // Calculate the inner width by removing the pane border.
811 awt::Rectangle
aInnerBox (mpPaneBorderPainter
->RemoveBorder (
814 sal_Int32(nOuterWidth
+0.5),sal_Int32(nOuterWidth
)),
815 drawing::framework::BorderType_TOTAL_BORDER
));
817 // Calculate the inner height with the help of the slide aspect ratio.
818 const double nCurrentSlideInnerHeight (
819 aInnerBox
.Width
/ mpPresenterController
->GetSlideAspectRatio());
821 // Add the pane border to get the outer box.
822 awt::Rectangle
aOuterBox (mpPaneBorderPainter
->AddBorder (
825 aInnerBox
.Width
,sal_Int32(nCurrentSlideInnerHeight
+0.5)),
826 drawing::framework::BorderType_TOTAL_BORDER
));
828 return awt::Size(aOuterBox
.Width
, aOuterBox
.Height
);
831 void PresenterWindowManager::NotifyLayoutModeChange()
833 document::EventObject aEvent
;
834 aEvent
.Source
= Reference
<XInterface
>(static_cast<XWeak
*>(this));
836 LayoutListenerContainer
aContainerCopy (maLayoutListeners
);
837 for (const auto& rxListener
: aContainerCopy
)
843 rxListener
->notifyEvent(aEvent
);
845 catch (lang::DisposedException
&)
847 RemoveLayoutListener(rxListener
);
849 catch (RuntimeException
&)
856 void PresenterWindowManager::NotifyDisposing()
858 lang::EventObject aEvent
;
859 aEvent
.Source
= static_cast<XWeak
*>(this);
861 LayoutListenerContainer aContainer
;
862 aContainer
.swap(maLayoutListeners
);
863 for (auto& rxListener
: aContainer
)
869 rxListener
->disposing(aEvent
);
871 catch (lang::DisposedException
&)
874 catch (RuntimeException
&)
881 void PresenterWindowManager::UpdateWindowSize (const Reference
<awt::XWindow
>& rxBorderWindow
)
883 PresenterPaneContainer::SharedPaneDescriptor
pDescriptor (
884 mpPaneContainer
->FindBorderWindow(rxBorderWindow
));
887 mxClipPolygon
= nullptr;
889 // ToTop is called last because it may invalidate the iterator.
890 if ( ! mbIsLayouting
)
891 mpPaneContainer
->ToTop(pDescriptor
);
895 void PresenterWindowManager::PaintBackground (const awt::Rectangle
& rUpdateBox
)
897 if ( ! mxParentWindow
.is())
900 Reference
<rendering::XGraphicDevice
> xDevice (mxParentCanvas
->getDevice());
904 // Create a polygon for the background and for clipping.
905 Reference
<rendering::XPolyPolygon2D
> xBackgroundPolygon (
906 PresenterGeometryHelper::CreatePolygon(mxParentWindow
->getPosSize(), xDevice
));
907 if ( ! mxClipPolygon
.is())
908 mxClipPolygon
= CreateClipPolyPolygon();
910 // Create View- and RenderState structs.
911 const rendering::ViewState
aViewState(
912 geometry::AffineMatrix2D(1,0,0, 0,1,0),
913 PresenterGeometryHelper::CreatePolygon(rUpdateBox
, xDevice
));
914 rendering::RenderState
aRenderState (
915 geometry::AffineMatrix2D(1,0,0, 0,1,0),
918 rendering::CompositeOperation::SOURCE
);
920 // Paint the background.
921 if (!mpBackgroundBitmap
)
924 ProvideBackgroundBitmap();
926 if (mxScaledBackgroundBitmap
.is())
928 const geometry::IntegerSize2D
aBitmapSize(mxScaledBackgroundBitmap
->getSize());
929 Sequence
<rendering::Texture
> aTextures
932 geometry::AffineMatrix2D( aBitmapSize
.Width
,0,0, 0,aBitmapSize
.Height
,0),
935 mxScaledBackgroundBitmap
,
938 rendering::StrokeAttributes(),
939 rendering::TexturingMode::REPEAT
,
940 rendering::TexturingMode::REPEAT
944 mxParentCanvas
->fillTexturedPolyPolygon(
952 const util::Color
aBackgroundColor (mpBackgroundBitmap
->maReplacementColor
);
953 aRenderState
.DeviceColor
[0] = ((aBackgroundColor
>> 16) & 0x0ff) / 255.0;
954 aRenderState
.DeviceColor
[1] = ((aBackgroundColor
>> 8) & 0x0ff) / 255.0;
955 aRenderState
.DeviceColor
[2] = ((aBackgroundColor
>> 0) & 0x0ff) / 255.0;
956 aRenderState
.DeviceColor
[3] = ((aBackgroundColor
>> 24) & 0x0ff) / 255.0;
957 mxParentCanvas
->fillPolyPolygon(
964 void PresenterWindowManager::ProvideBackgroundBitmap()
966 if ( mxScaledBackgroundBitmap
.is())
969 Reference
<rendering::XBitmap
> xBitmap (mpBackgroundBitmap
->GetNormalBitmap());
973 const bool bStretchVertical (mpBackgroundBitmap
->meVerticalTexturingMode
974 == PresenterBitmapDescriptor::Stretch
);
975 const bool bStretchHorizontal (mpBackgroundBitmap
->meHorizontalTexturingMode
976 == PresenterBitmapDescriptor::Stretch
);
977 if (bStretchHorizontal
|| bStretchVertical
)
979 geometry::RealSize2D aSize
;
980 if (bStretchVertical
)
981 aSize
.Height
= mxParentWindow
->getPosSize().Height
;
983 aSize
.Height
= xBitmap
->getSize().Height
;
984 if (bStretchHorizontal
)
985 aSize
.Width
= mxParentWindow
->getPosSize().Width
;
987 aSize
.Width
= xBitmap
->getSize().Width
;
988 mxScaledBackgroundBitmap
= xBitmap
->getScaledBitmap(aSize
, false);
992 mxScaledBackgroundBitmap
= xBitmap
;
996 Reference
<rendering::XPolyPolygon2D
> PresenterWindowManager::CreateClipPolyPolygon() const
998 // Create a clip polygon that includes the whole update area but has the
999 // content windows as holes.
1000 const sal_Int32
nPaneCount (mpPaneContainer
->maPanes
.size());
1001 ::std::vector
<awt::Rectangle
> aRectangles
;
1002 aRectangles
.reserve(1+nPaneCount
);
1003 aRectangles
.push_back(mxParentWindow
->getPosSize());
1004 for (const auto& pDescriptor
: mpPaneContainer
->maPanes
)
1006 if ( ! pDescriptor
->mbIsActive
)
1008 if ( ! pDescriptor
->mbIsOpaque
)
1010 if ( ! pDescriptor
->mxBorderWindow
.is() || ! pDescriptor
->mxContentWindow
.is())
1012 Reference
<awt::XWindow2
> xWindow (pDescriptor
->mxBorderWindow
, UNO_QUERY
);
1013 if (xWindow
.is() && ! xWindow
->isVisible())
1016 const awt::Rectangle
aOuterBorderBox (pDescriptor
->mxBorderWindow
->getPosSize());
1017 awt::Rectangle
aInnerBorderBox (pDescriptor
->mxContentWindow
->getPosSize());
1018 aInnerBorderBox
.X
+= aOuterBorderBox
.X
;
1019 aInnerBorderBox
.Y
+= aOuterBorderBox
.Y
;
1020 aRectangles
.push_back(aInnerBorderBox
);
1022 Reference
<rendering::XPolyPolygon2D
> xPolyPolygon (
1023 PresenterGeometryHelper::CreatePolygon(
1025 mxParentCanvas
->getDevice()));
1026 if (xPolyPolygon
.is())
1027 xPolyPolygon
->setFillRule(rendering::FillRule_EVEN_ODD
);
1028 return xPolyPolygon
;
1031 void PresenterWindowManager::Update()
1033 mxClipPolygon
= nullptr;
1034 mbIsLayoutPending
= true;
1036 mpPresenterController
->GetPaintManager()->Invalidate(mxParentWindow
);
1039 void PresenterWindowManager::ThrowIfDisposed() const
1041 if (rBHelper
.bDisposed
|| rBHelper
.bInDispose
)
1043 throw lang::DisposedException (
1044 "PresenterWindowManager has already been disposed",
1045 const_cast<uno::XWeak
*>(static_cast<const uno::XWeak
*>(this)));
1049 } // end of namespace ::sdext::presenter
1051 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */