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
{ namespace 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),
71 mbIsMouseClickPending(false)
76 PresenterWindowManager::~PresenterWindowManager()
80 void SAL_CALL
PresenterWindowManager::disposing()
84 SetParentPane(nullptr);
86 Reference
<lang::XComponent
> xComponent (mxPaneBorderManager
, UNO_QUERY
);
88 xComponent
->dispose();
89 mxPaneBorderManager
= nullptr;
91 for (const auto& rxPane
: mpPaneContainer
->maPanes
)
93 if (rxPane
->mxBorderWindow
.is())
95 rxPane
->mxBorderWindow
->removeWindowListener(this);
96 rxPane
->mxBorderWindow
->removeFocusListener(this);
97 rxPane
->mxBorderWindow
->removeMouseListener(this);
102 void PresenterWindowManager::SetParentPane (
103 const Reference
<drawing::framework::XPane
>& rxPane
)
105 if (mxParentWindow
.is())
107 mxParentWindow
->removeWindowListener(this);
108 mxParentWindow
->removePaintListener(this);
109 mxParentWindow
->removeMouseListener(this);
110 mxParentWindow
->removeFocusListener(this);
112 mxParentWindow
= nullptr;
113 mxParentCanvas
= nullptr;
117 mxParentWindow
= rxPane
->getWindow();
118 mxParentCanvas
= rxPane
->getCanvas();
122 mxParentWindow
= nullptr;
125 if (mxParentWindow
.is())
127 mxParentWindow
->addWindowListener(this);
128 mxParentWindow
->addPaintListener(this);
129 mxParentWindow
->addMouseListener(this);
130 mxParentWindow
->addFocusListener(this);
132 // We paint our own background, make that of the parent window transparent.
133 Reference
<awt::XWindowPeer
> xPeer (mxParentWindow
, UNO_QUERY
);
135 xPeer
->setBackground(util::Color(0xff000000));
139 void PresenterWindowManager::SetTheme (const std::shared_ptr
<PresenterTheme
>& rpTheme
)
143 // Get background bitmap or background color from the theme.
145 if (mpTheme
!= nullptr)
147 mpBackgroundBitmap
= mpTheme
->GetBitmap(OUString(), "Background");
151 void PresenterWindowManager::NotifyViewCreation (const Reference
<XView
>& rxView
)
153 PresenterPaneContainer::SharedPaneDescriptor
pDescriptor (
154 mpPaneContainer
->FindPaneId(rxView
->getResourceId()->getAnchor()));
155 OSL_ASSERT(pDescriptor
.get() != nullptr);
156 if (pDescriptor
.get() != nullptr)
160 mpPresenterController
->GetPaintManager()->Invalidate(
161 pDescriptor
->mxContentWindow
,
162 sal_Int16(awt::InvalidateStyle::TRANSPARENT
163 | awt::InvalidateStyle::CHILDREN
));
167 void PresenterWindowManager::SetPanePosSizeAbsolute (
168 const OUString
& rsPaneURL
,
172 const double nHeight
)
174 PresenterPaneContainer::SharedPaneDescriptor
pDescriptor (
175 mpPaneContainer
->FindPaneURL(rsPaneURL
));
176 if (pDescriptor
.get() != nullptr)
178 if (pDescriptor
->mxBorderWindow
.is())
179 pDescriptor
->mxBorderWindow
->setPosSize(
180 ::sal::static_int_cast
<sal_Int32
>(nX
),
181 ::sal::static_int_cast
<sal_Int32
>(nY
),
182 ::sal::static_int_cast
<sal_Int32
>(nWidth
),
183 ::sal::static_int_cast
<sal_Int32
>(nHeight
),
184 awt::PosSize::POSSIZE
);
188 void PresenterWindowManager::SetPaneBorderPainter (
189 const ::rtl::Reference
<PresenterPaneBorderPainter
>& rPainter
)
191 mpPaneBorderPainter
= rPainter
;
194 //----- XWindowListener -------------------------------------------------------
196 void SAL_CALL
PresenterWindowManager::windowResized (const awt::WindowEvent
& rEvent
)
199 if (rEvent
.Source
== mxParentWindow
)
205 Reference
<awt::XWindow
> xWindow (rEvent
.Source
,UNO_QUERY
);
208 UpdateWindowSize(xWindow
);
210 // Make sure the background of a transparent window is painted.
211 mpPresenterController
->GetPaintManager()->Invalidate(mxParentWindow
);
216 void SAL_CALL
PresenterWindowManager::windowMoved (const awt::WindowEvent
& rEvent
)
219 if (rEvent
.Source
!= mxParentWindow
)
221 Reference
<awt::XWindow
> xWindow (rEvent
.Source
,UNO_QUERY
);
222 UpdateWindowSize(xWindow
);
224 // Make sure the background of a transparent window is painted.
225 mpPresenterController
->GetPaintManager()->Invalidate(xWindow
);
229 void SAL_CALL
PresenterWindowManager::windowShown (const lang::EventObject
&) {}
231 void SAL_CALL
PresenterWindowManager::windowHidden (const lang::EventObject
&) {}
233 //----- XPaintListener --------------------------------------------------------
235 void SAL_CALL
PresenterWindowManager::windowPaint (const awt::PaintEvent
& rEvent
)
239 if ( ! mxParentWindow
.is())
241 if ( ! mxParentCanvas
.is())
244 if (mpTheme
== nullptr)
249 if (mbIsLayoutPending
)
251 PaintBackground(rEvent
.UpdateRect
);
252 PaintChildren(rEvent
);
254 catch (RuntimeException
&)
256 OSL_FAIL("paint failed!");
260 //----- XMouseListener --------------------------------------------------------
262 void SAL_CALL
PresenterWindowManager::mousePressed (const css::awt::MouseEvent
&)
264 if (!mbIsSlideSorterActive
) // tdf#127921
265 mbIsMouseClickPending
= true;
268 void SAL_CALL
PresenterWindowManager::mouseReleased (const css::awt::MouseEvent
& rEvent
)
270 if (mbIsMouseClickPending
)
272 mbIsMouseClickPending
= false;
273 mpPresenterController
->HandleMouseClick(rEvent
);
277 void SAL_CALL
PresenterWindowManager::mouseEntered (const css::awt::MouseEvent
&)
279 mbIsMouseClickPending
= false;
282 void SAL_CALL
PresenterWindowManager::mouseExited (const css::awt::MouseEvent
&)
284 mbIsMouseClickPending
= false;
287 //----- XFocusListener --------------------------------------------------------
289 void SAL_CALL
PresenterWindowManager::focusGained (const css::awt::FocusEvent
& /*rEvent*/)
294 void SAL_CALL
PresenterWindowManager::focusLost (const css::awt::FocusEvent
&)
299 //----- XEventListener --------------------------------------------------------
301 void SAL_CALL
PresenterWindowManager::disposing (const lang::EventObject
& rEvent
)
303 if (rEvent
.Source
== mxParentWindow
)
304 mxParentWindow
= nullptr;
308 void PresenterWindowManager::PaintChildren (const awt::PaintEvent
& rEvent
) const
310 // Call windowPaint on all children that lie in or touch the
312 for (const auto& rxPane
: mpPaneContainer
->maPanes
)
316 // Make sure that the pane shall and can be painted.
317 if ( ! rxPane
->mbIsActive
)
319 if (rxPane
->mbIsSprite
)
321 if ( ! rxPane
->mxPane
.is())
323 if ( ! rxPane
->mxBorderWindow
.is())
325 Reference
<awt::XWindow
> xBorderWindow (rxPane
->mxBorderWindow
);
326 if ( ! xBorderWindow
.is())
329 // Get the area in which the border of the pane has to be painted.
330 const awt::Rectangle
aBorderBox (xBorderWindow
->getPosSize());
331 const awt::Rectangle
aBorderUpdateBox(
332 PresenterGeometryHelper::Intersection(
335 if (aBorderUpdateBox
.Width
<=0 || aBorderUpdateBox
.Height
<=0)
338 const awt::Rectangle
aLocalBorderUpdateBox(
339 PresenterGeometryHelper::TranslateRectangle(
344 // Invalidate the area of the content window.
345 mpPresenterController
->GetPaintManager()->Invalidate(
347 aLocalBorderUpdateBox
,
348 sal_Int16(awt::InvalidateStyle::CHILDREN
349 | awt::InvalidateStyle::NOTRANSPARENT
));
351 catch (RuntimeException
&)
353 OSL_FAIL("paint children failed!");
358 void PresenterWindowManager::SetLayoutMode (const LayoutMode eMode
)
360 OSL_ASSERT(mpPresenterController
.get() != nullptr);
362 if (meLayoutMode
== eMode
363 && !mbIsSlideSorterActive
364 && !mbIsHelpViewActive
)
367 meLayoutMode
= eMode
;
368 mbIsSlideSorterActive
= false;
369 mbIsHelpViewActive
= false;
371 mpPresenterController
->RequestViews(
372 mbIsSlideSorterActive
,
373 meLayoutMode
==LM_Notes
,
376 NotifyLayoutModeChange();
379 void PresenterWindowManager::SetSlideSorterState (bool bIsActive
)
381 if (mbIsSlideSorterActive
== bIsActive
)
384 mbIsSlideSorterActive
= bIsActive
;
385 if (mbIsSlideSorterActive
)
386 mbIsHelpViewActive
= false;
387 StoreViewMode(GetViewMode());
389 mpPresenterController
->RequestViews(
390 mbIsSlideSorterActive
,
391 meLayoutMode
==LM_Notes
,
394 NotifyLayoutModeChange();
397 void PresenterWindowManager::SetHelpViewState (bool bIsActive
)
399 if (mbIsHelpViewActive
== bIsActive
)
402 mbIsHelpViewActive
= bIsActive
;
403 if (mbIsHelpViewActive
)
404 mbIsSlideSorterActive
= false;
405 StoreViewMode(GetViewMode());
407 mpPresenterController
->RequestViews(
408 mbIsSlideSorterActive
,
409 meLayoutMode
==LM_Notes
,
412 NotifyLayoutModeChange();
415 void PresenterWindowManager::SetViewMode (const ViewMode eMode
)
420 SetSlideSorterState(false);
421 SetHelpViewState(false);
422 SetLayoutMode(LM_Standard
);
426 SetSlideSorterState(false);
427 SetHelpViewState(false);
428 SetLayoutMode(LM_Notes
);
431 case VM_SlideOverview
:
432 SetHelpViewState(false);
433 SetSlideSorterState(true);
437 SetHelpViewState(true);
438 SetSlideSorterState(false);
442 StoreViewMode(eMode
);
445 PresenterWindowManager::ViewMode
PresenterWindowManager::GetViewMode() const
447 if (mbIsHelpViewActive
)
449 else if (mbIsSlideSorterActive
)
450 return VM_SlideOverview
;
451 else if (meLayoutMode
== LM_Notes
)
457 void PresenterWindowManager::RestoreViewMode()
460 PresenterConfigurationAccess
aConfiguration (
462 "/org.openoffice.Office.PresenterScreen/",
463 PresenterConfigurationAccess::READ_ONLY
);
464 aConfiguration
.GetConfigurationNode("Presenter/InitialViewMode") >>= nMode
;
469 SetViewMode(VM_Standard
);
473 SetViewMode(VM_Notes
);
477 SetViewMode(VM_SlideOverview
);
482 void PresenterWindowManager::StoreViewMode (const ViewMode eViewMode
)
486 PresenterConfigurationAccess
aConfiguration (
488 "/org.openoffice.Office.PresenterScreen/",
489 PresenterConfigurationAccess::READ_WRITE
);
490 aConfiguration
.GoToChild("Presenter");
496 aValue
<<= sal_Int32(0);
500 aValue
<<= sal_Int32(1);
503 case VM_SlideOverview
:
504 aValue
<<= sal_Int32(2);
508 aConfiguration
.SetProperty ("InitialViewMode", aValue
);
509 aConfiguration
.CommitChanges();
516 void PresenterWindowManager::AddLayoutListener (
517 const Reference
<document::XEventListener
>& rxListener
)
519 maLayoutListeners
.push_back(rxListener
);
522 void PresenterWindowManager::RemoveLayoutListener (
523 const Reference
<document::XEventListener
>& rxListener
)
525 // Assume that there are no multiple entries.
526 auto iListener
= std::find(maLayoutListeners
.begin(), maLayoutListeners
.end(), rxListener
);
527 if (iListener
!= maLayoutListeners
.end())
528 maLayoutListeners
.erase(iListener
);
531 void PresenterWindowManager::Layout()
533 if (!mxParentWindow
.is() || mbIsLayouting
)
536 mbIsLayoutPending
= false;
537 mbIsLayouting
= true;
538 mxScaledBackgroundBitmap
= nullptr;
539 mxClipPolygon
= nullptr;
543 if (mbIsSlideSorterActive
)
544 LayoutSlideSorterMode();
545 else if (mbIsHelpViewActive
)
548 switch (meLayoutMode
)
552 LayoutStandardMode();
566 mbIsLayouting
= false;
569 void PresenterWindowManager::LayoutStandardMode()
571 awt::Rectangle aBox
= mxParentWindow
->getPosSize();
573 const double nGoldenRatio ((1 + sqrt(5.0)) / 2);
574 const double nGap (20);
575 const double nHorizontalSlideDivide (aBox
.Width
/ nGoldenRatio
);
576 double nSlidePreviewTop (0);
579 // For the current slide view calculate the outer height from the outer
580 // width. This takes into account the slide aspect ratio and thus has to
581 // go over the inner pane size.
582 PresenterPaneContainer::SharedPaneDescriptor
pPane (
583 mpPaneContainer
->FindPaneURL(PresenterPaneFactory::msCurrentSlidePreviewPaneURL
));
584 if (pPane
.get() != nullptr)
586 const awt::Size
aCurrentSlideOuterBox(CalculatePaneSize(
587 nHorizontalSlideDivide
- 1.5*nGap
,
588 PresenterPaneFactory::msCurrentSlidePreviewPaneURL
));
589 nSlidePreviewTop
= (aBox
.Height
- aCurrentSlideOuterBox
.Height
) / 2;
591 /// check whether RTL interface or not
592 if(AllSettings::GetLayoutRTL())
593 Temp
=aBox
.Width
- aCurrentSlideOuterBox
.Width
- nGap
;
594 SetPanePosSizeAbsolute (
595 PresenterPaneFactory::msCurrentSlidePreviewPaneURL
,
598 aCurrentSlideOuterBox
.Width
,
599 aCurrentSlideOuterBox
.Height
);
602 // For the next slide view calculate the outer height from the outer
603 // width. This takes into account the slide aspect ratio and thus has to
604 // go over the inner pane size.
605 pPane
= mpPaneContainer
->FindPaneURL(PresenterPaneFactory::msNextSlidePreviewPaneURL
);
606 if (pPane
.get() != nullptr)
608 const awt::Size
aNextSlideOuterBox (CalculatePaneSize(
609 aBox
.Width
- nHorizontalSlideDivide
- 1.5*nGap
,
610 PresenterPaneFactory::msNextSlidePreviewPaneURL
));
611 double Temp
=aBox
.Width
- aNextSlideOuterBox
.Width
- nGap
;
612 /// check whether RTL interface or not
613 if(AllSettings::GetLayoutRTL())
615 SetPanePosSizeAbsolute (
616 PresenterPaneFactory::msNextSlidePreviewPaneURL
,
619 aNextSlideOuterBox
.Width
,
620 aNextSlideOuterBox
.Height
);
626 void PresenterWindowManager::LayoutNotesMode()
628 awt::Rectangle aBox
= mxParentWindow
->getPosSize();
630 const geometry::RealRectangle2D
aToolBarBox (LayoutToolBar());
632 const double nGoldenRatio ((1 + sqrt(5.0)) / 2);
633 const double nGap (20);
634 const double nPrimaryWidth (aBox
.Width
/ nGoldenRatio
);
635 const double nSecondaryWidth (aBox
.Width
- nPrimaryWidth
);
636 const double nTertiaryWidth (nSecondaryWidth
/ nGoldenRatio
);
637 double nSlidePreviewTop (0);
638 double nNotesViewBottom (aToolBarBox
.Y1
- nGap
);
639 /// check whether RTL interface or not
642 // The notes view has no fixed aspect ratio.
643 PresenterPaneContainer::SharedPaneDescriptor
pPane (
644 mpPaneContainer
->FindPaneURL(PresenterPaneFactory::msNotesPaneURL
));
645 if (pPane
.get() != nullptr)
647 const geometry::RealSize2D
aNotesViewOuterSize(
648 nPrimaryWidth
- 1.5*nGap
+ 0.5,
650 nSlidePreviewTop
= (aBox
.Height
651 - aToolBarBox
.Y2
+ aToolBarBox
.Y1
- aNotesViewOuterSize
.Height
) / 2;
652 /// check whether RTL interface or not
653 double Temp
=aBox
.Width
- aNotesViewOuterSize
.Width
- nGap
;
654 if(AllSettings::GetLayoutRTL())
656 SetPanePosSizeAbsolute (
657 PresenterPaneFactory::msNotesPaneURL
,
660 aNotesViewOuterSize
.Width
,
661 aNotesViewOuterSize
.Height
);
662 nNotesViewBottom
= nSlidePreviewTop
+ aNotesViewOuterSize
.Height
;
665 // For the current slide view calculate the outer height from the outer
666 // width. This takes into account the slide aspect ratio and thus has to
667 // go over the inner pane size.
668 pPane
= mpPaneContainer
->FindPaneURL(PresenterPaneFactory::msCurrentSlidePreviewPaneURL
);
669 if (pPane
.get() != nullptr)
671 const awt::Size
aCurrentSlideOuterBox(CalculatePaneSize(
672 nSecondaryWidth
- 1.5*nGap
,
673 PresenterPaneFactory::msCurrentSlidePreviewPaneURL
));
674 /// check whether RTL interface or not
676 if(AllSettings::GetLayoutRTL())
677 Temp
=aBox
.Width
- aCurrentSlideOuterBox
.Width
- nGap
;
678 SetPanePosSizeAbsolute (
679 PresenterPaneFactory::msCurrentSlidePreviewPaneURL
,
682 aCurrentSlideOuterBox
.Width
,
683 aCurrentSlideOuterBox
.Height
);
686 // For the next slide view calculate the outer height from the outer
687 // width. This takes into account the slide aspect ratio and thus has to
688 // go over the inner pane size.
689 pPane
= mpPaneContainer
->FindPaneURL(PresenterPaneFactory::msNextSlidePreviewPaneURL
);
690 if (pPane
.get() == nullptr)
693 const awt::Size
aNextSlideOuterBox (CalculatePaneSize(
695 PresenterPaneFactory::msNextSlidePreviewPaneURL
));
696 /// check whether RTL interface or not
698 if(AllSettings::GetLayoutRTL())
699 Temp
=aBox
.Width
- aNextSlideOuterBox
.Width
- nGap
;
700 SetPanePosSizeAbsolute (
701 PresenterPaneFactory::msNextSlidePreviewPaneURL
,
703 nNotesViewBottom
- aNextSlideOuterBox
.Height
,
704 aNextSlideOuterBox
.Width
,
705 aNextSlideOuterBox
.Height
);
710 void PresenterWindowManager::LayoutSlideSorterMode()
712 const geometry::RealRectangle2D
aToolBarBox (LayoutToolBar());
714 awt::Rectangle aWindowBox
= mxParentWindow
->getPosSize();
715 const double nGap (20);
716 SetPanePosSizeAbsolute(
717 mpPaneContainer
->GetPaneURLForViewURL(PresenterViewFactory::msSlideSorterURL
),
720 aWindowBox
.Width
- 2*nGap
,
721 aToolBarBox
.Y1
- 2*nGap
);
724 void PresenterWindowManager::LayoutHelpMode()
726 const geometry::RealRectangle2D
aToolBarBox (LayoutToolBar());
728 awt::Rectangle aWindowBox
= mxParentWindow
->getPosSize();
729 const double nGap (20);
730 const double nGoldenRatio ((1 + sqrt(5.0)) / 2);
731 const double nWidth
= ::std::min(aWindowBox
.Width
- 2*nGap
, aWindowBox
.Width
/nGoldenRatio
);
732 SetPanePosSizeAbsolute(
733 mpPaneContainer
->GetPaneURLForViewURL(PresenterViewFactory::msHelpViewURL
),
734 (aWindowBox
.Width
- nWidth
)/2,
737 aToolBarBox
.Y1
- 2*nGap
);
740 geometry::RealRectangle2D
PresenterWindowManager::LayoutToolBar()
742 double nToolBarWidth (400);
743 double nToolBarHeight (80);
745 // Get access to the tool bar.
746 PresenterPaneContainer::SharedPaneDescriptor
pDescriptor(
747 mpPaneContainer
->FindPaneURL(PresenterPaneFactory::msToolBarPaneURL
));
748 if (pDescriptor
.get() != nullptr)
750 PresenterToolBarView
* pToolBarView
751 = dynamic_cast<PresenterToolBarView
*>(pDescriptor
->mxView
.get());
752 if (pToolBarView
!= nullptr && pToolBarView
->GetPresenterToolBar().is())
754 geometry::RealSize2D
aSize (pToolBarView
->GetPresenterToolBar()->GetMinimalSize());
756 if (mpPaneBorderPainter
.is())
758 const awt::Rectangle
aBox (mpPaneBorderPainter
->addBorder (
759 PresenterPaneFactory::msToolBarPaneURL
,
763 PresenterGeometryHelper::Round(aSize
.Width
),
764 PresenterGeometryHelper::Round(aSize
.Height
)),
765 css::drawing::framework::BorderType_TOTAL_BORDER
));
767 nToolBarWidth
= aBox
.Width
;
768 nToolBarHeight
= aBox
.Height
;
772 nToolBarWidth
= aSize
.Width
+ 20;
773 nToolBarHeight
= aSize
.Height
+ 10;
778 const awt::Rectangle aBox
= mxParentWindow
->getPosSize();
779 const double nToolBarX ((aBox
.Width
- nToolBarWidth
) / 2);
780 const double nToolBarY (aBox
.Height
- nToolBarHeight
);
781 SetPanePosSizeAbsolute(
782 PresenterPaneFactory::msToolBarPaneURL
,
788 return geometry::RealRectangle2D(
791 nToolBarX
+ nToolBarWidth
- 1,
792 nToolBarY
+ nToolBarHeight
- 1);
795 awt::Size
PresenterWindowManager::CalculatePaneSize (
796 const double nOuterWidth
,
797 const OUString
& rsPaneURL
)
799 // Calculate the inner width by removing the pane border.
800 awt::Rectangle
aInnerBox (mpPaneBorderPainter
->RemoveBorder (
803 sal_Int32(nOuterWidth
+0.5),sal_Int32(nOuterWidth
)),
804 drawing::framework::BorderType_TOTAL_BORDER
));
806 // Calculate the inner height with the help of the slide aspect ratio.
807 const double nCurrentSlideInnerHeight (
808 aInnerBox
.Width
/ mpPresenterController
->GetSlideAspectRatio());
810 // Add the pane border to get the outer box.
811 awt::Rectangle
aOuterBox (mpPaneBorderPainter
->AddBorder (
814 aInnerBox
.Width
,sal_Int32(nCurrentSlideInnerHeight
+0.5)),
815 drawing::framework::BorderType_TOTAL_BORDER
));
817 return awt::Size(aOuterBox
.Width
, aOuterBox
.Height
);
820 void PresenterWindowManager::NotifyLayoutModeChange()
822 document::EventObject aEvent
;
823 aEvent
.Source
= Reference
<XInterface
>(static_cast<XWeak
*>(this));
825 LayoutListenerContainer
aContainerCopy (maLayoutListeners
);
826 for (const auto& rxListener
: aContainerCopy
)
832 rxListener
->notifyEvent(aEvent
);
834 catch (lang::DisposedException
&)
836 RemoveLayoutListener(rxListener
);
838 catch (RuntimeException
&)
845 void PresenterWindowManager::NotifyDisposing()
847 lang::EventObject aEvent
;
848 aEvent
.Source
= static_cast<XWeak
*>(this);
850 LayoutListenerContainer aContainer
;
851 aContainer
.swap(maLayoutListeners
);
852 for (auto& rxListener
: aContainer
)
858 rxListener
->disposing(aEvent
);
860 catch (lang::DisposedException
&)
863 catch (RuntimeException
&)
870 void PresenterWindowManager::UpdateWindowSize (const Reference
<awt::XWindow
>& rxBorderWindow
)
872 PresenterPaneContainer::SharedPaneDescriptor
pDescriptor (
873 mpPaneContainer
->FindBorderWindow(rxBorderWindow
));
874 if (pDescriptor
.get() != nullptr)
876 mxClipPolygon
= nullptr;
878 // ToTop is called last because it may invalidate the iterator.
879 if ( ! mbIsLayouting
)
880 mpPaneContainer
->ToTop(pDescriptor
);
884 void PresenterWindowManager::PaintBackground (const awt::Rectangle
& rUpdateBox
)
886 if ( ! mxParentWindow
.is())
889 Reference
<rendering::XGraphicDevice
> xDevice (mxParentCanvas
->getDevice());
893 // Create a polygon for the background and for clipping.
894 Reference
<rendering::XPolyPolygon2D
> xBackgroundPolygon (
895 PresenterGeometryHelper::CreatePolygon(mxParentWindow
->getPosSize(), xDevice
));
896 if ( ! mxClipPolygon
.is())
897 mxClipPolygon
= CreateClipPolyPolygon();
899 // Create View- and RenderState structs.
900 const rendering::ViewState
aViewState(
901 geometry::AffineMatrix2D(1,0,0, 0,1,0),
902 PresenterGeometryHelper::CreatePolygon(rUpdateBox
, xDevice
));
903 rendering::RenderState
aRenderState (
904 geometry::AffineMatrix2D(1,0,0, 0,1,0),
907 rendering::CompositeOperation::SOURCE
);
909 // Paint the background.
910 if (mpBackgroundBitmap
.get() == nullptr)
913 ProvideBackgroundBitmap();
915 if (mxScaledBackgroundBitmap
.is())
917 Sequence
<rendering::Texture
> aTextures (1);
918 const geometry::IntegerSize2D
aBitmapSize(mxScaledBackgroundBitmap
->getSize());
919 aTextures
[0] = rendering::Texture (
920 geometry::AffineMatrix2D(
921 aBitmapSize
.Width
,0,0,
922 0,aBitmapSize
.Height
,0),
925 mxScaledBackgroundBitmap
,
928 rendering::StrokeAttributes(),
929 rendering::TexturingMode::REPEAT
,
930 rendering::TexturingMode::REPEAT
);
932 mxParentCanvas
->fillTexturedPolyPolygon(
940 const util::Color
aBackgroundColor (mpBackgroundBitmap
->maReplacementColor
);
941 aRenderState
.DeviceColor
[0] = ((aBackgroundColor
>> 16) & 0x0ff) / 255.0;
942 aRenderState
.DeviceColor
[1] = ((aBackgroundColor
>> 8) & 0x0ff) / 255.0;
943 aRenderState
.DeviceColor
[2] = ((aBackgroundColor
>> 0) & 0x0ff) / 255.0;
944 aRenderState
.DeviceColor
[3] = ((aBackgroundColor
>> 24) & 0x0ff) / 255.0;
945 mxParentCanvas
->fillPolyPolygon(
952 void PresenterWindowManager::ProvideBackgroundBitmap()
954 if ( mxScaledBackgroundBitmap
.is())
957 Reference
<rendering::XBitmap
> xBitmap (mpBackgroundBitmap
->GetNormalBitmap());
961 const bool bStretchVertical (mpBackgroundBitmap
->meVerticalTexturingMode
962 == PresenterBitmapDescriptor::Stretch
);
963 const bool bStretchHorizontal (mpBackgroundBitmap
->meHorizontalTexturingMode
964 == PresenterBitmapDescriptor::Stretch
);
965 if (bStretchHorizontal
|| bStretchVertical
)
967 geometry::RealSize2D aSize
;
968 if (bStretchVertical
)
969 aSize
.Height
= mxParentWindow
->getPosSize().Height
;
971 aSize
.Height
= xBitmap
->getSize().Height
;
972 if (bStretchHorizontal
)
973 aSize
.Width
= mxParentWindow
->getPosSize().Width
;
975 aSize
.Width
= xBitmap
->getSize().Width
;
976 mxScaledBackgroundBitmap
= xBitmap
->getScaledBitmap(aSize
, false);
980 mxScaledBackgroundBitmap
= xBitmap
;
984 Reference
<rendering::XPolyPolygon2D
> PresenterWindowManager::CreateClipPolyPolygon() const
986 // Create a clip polygon that includes the whole update area but has the
987 // content windows as holes.
988 const sal_Int32
nPaneCount (mpPaneContainer
->maPanes
.size());
989 ::std::vector
<awt::Rectangle
> aRectangles
;
990 aRectangles
.reserve(1+nPaneCount
);
991 aRectangles
.push_back(mxParentWindow
->getPosSize());
992 for (const auto& pDescriptor
: mpPaneContainer
->maPanes
)
994 if ( ! pDescriptor
->mbIsActive
)
996 if ( ! pDescriptor
->mbIsOpaque
)
998 if ( ! pDescriptor
->mxBorderWindow
.is() || ! pDescriptor
->mxContentWindow
.is())
1000 Reference
<awt::XWindow2
> xWindow (pDescriptor
->mxBorderWindow
, UNO_QUERY
);
1001 if (xWindow
.is() && ! xWindow
->isVisible())
1004 const awt::Rectangle
aOuterBorderBox (pDescriptor
->mxBorderWindow
->getPosSize());
1005 awt::Rectangle
aInnerBorderBox (pDescriptor
->mxContentWindow
->getPosSize());
1006 aInnerBorderBox
.X
+= aOuterBorderBox
.X
;
1007 aInnerBorderBox
.Y
+= aOuterBorderBox
.Y
;
1008 aRectangles
.push_back(aInnerBorderBox
);
1010 Reference
<rendering::XPolyPolygon2D
> xPolyPolygon (
1011 PresenterGeometryHelper::CreatePolygon(
1013 mxParentCanvas
->getDevice()));
1014 if (xPolyPolygon
.is())
1015 xPolyPolygon
->setFillRule(rendering::FillRule_EVEN_ODD
);
1016 return xPolyPolygon
;
1019 void PresenterWindowManager::Update()
1021 mxClipPolygon
= nullptr;
1022 mbIsLayoutPending
= true;
1024 mpPresenterController
->GetPaintManager()->Invalidate(mxParentWindow
);
1027 void PresenterWindowManager::ThrowIfDisposed() const
1029 if (rBHelper
.bDisposed
|| rBHelper
.bInDispose
)
1031 throw lang::DisposedException (
1032 "PresenterWindowManager has already been disposed",
1033 const_cast<uno::XWeak
*>(static_cast<const uno::XWeak
*>(this)));
1037 } } // end of namespace ::sdext::presenter
1039 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */