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/svapp.hxx>
21 #include <vcl/settings.hxx>
22 #include "PresenterWindowManager.hxx"
23 #include "PresenterController.hxx"
24 #include "PresenterGeometryHelper.hxx"
25 #include "PresenterHelper.hxx"
26 #include "PresenterPaintManager.hxx"
27 #include "PresenterPaneBase.hxx"
28 #include "PresenterPaneBorderPainter.hxx"
29 #include "PresenterPaneContainer.hxx"
30 #include "PresenterPaneFactory.hxx"
31 #include "PresenterSprite.hxx"
32 #include "PresenterToolBar.hxx"
33 #include "PresenterViewFactory.hxx"
34 #include "PresenterTheme.hxx"
35 #include <com/sun/star/awt/InvalidateStyle.hpp>
36 #include <com/sun/star/awt/PosSize.hpp>
37 #include <com/sun/star/awt/SystemPointer.hpp>
38 #include <com/sun/star/awt/XDevice.hpp>
39 #include <com/sun/star/awt/XWindow2.hpp>
40 #include <com/sun/star/awt/XWindowPeer.hpp>
41 #include <com/sun/star/awt/WindowAttribute.hpp>
42 #include <com/sun/star/container/XChild.hpp>
43 #include <com/sun/star/drawing/framework/ResourceId.hpp>
44 #include <com/sun/star/rendering/CompositeOperation.hpp>
45 #include <com/sun/star/rendering/FillRule.hpp>
46 #include <com/sun/star/rendering/PathCapType.hpp>
47 #include <com/sun/star/rendering/PathJoinType.hpp>
48 #include <com/sun/star/rendering/Texture.hpp>
49 #include <com/sun/star/rendering/TexturingMode.hpp>
50 #include <com/sun/star/rendering/XSpriteCanvas.hpp>
53 using namespace ::com::sun::star
;
54 using namespace ::com::sun::star::uno
;
55 using namespace ::com::sun::star::drawing::framework
;
57 namespace sdext
{ namespace presenter
{
59 //===== PresenterWindowManager ================================================
61 PresenterWindowManager::PresenterWindowManager (
62 const Reference
<XComponentContext
>& rxContext
,
63 const ::rtl::Reference
<PresenterPaneContainer
>& rpPaneContainer
,
64 const ::rtl::Reference
<PresenterController
>& rpPresenterController
)
65 : PresenterWindowManagerInterfaceBase(m_aMutex
),
66 mxComponentContext(rxContext
),
67 mpPresenterController(rpPresenterController
),
70 mxPaneBorderManager(),
71 mpPaneBorderPainter(),
72 mpPaneContainer(rpPaneContainer
),
73 mbIsLayoutPending(true),
77 mxScaledBackgroundBitmap(),
79 meLayoutMode(LM_Generic
),
80 mbIsSlideSorterActive(false),
81 mbIsHelpViewActive(false),
83 mbIsMouseClickPending(false)
88 PresenterWindowManager::~PresenterWindowManager()
92 void SAL_CALL
PresenterWindowManager::disposing()
96 SetParentPane(nullptr);
98 Reference
<lang::XComponent
> xComponent (mxPaneBorderManager
, UNO_QUERY
);
100 xComponent
->dispose();
101 mxPaneBorderManager
= nullptr;
103 PresenterPaneContainer::PaneList::const_iterator iPane
;
104 PresenterPaneContainer::PaneList::const_iterator
iEnd (mpPaneContainer
->maPanes
.end());
105 for (iPane
=mpPaneContainer
->maPanes
.begin(); iPane
!=iEnd
; ++iPane
)
107 if ((*iPane
)->mxBorderWindow
.is())
109 (*iPane
)->mxBorderWindow
->removeWindowListener(this);
110 (*iPane
)->mxBorderWindow
->removeFocusListener(this);
111 (*iPane
)->mxBorderWindow
->removeMouseListener(this);
116 void PresenterWindowManager::SetParentPane (
117 const Reference
<drawing::framework::XPane
>& rxPane
)
119 if (mxParentWindow
.is())
121 mxParentWindow
->removeWindowListener(this);
122 mxParentWindow
->removePaintListener(this);
123 mxParentWindow
->removeMouseListener(this);
124 mxParentWindow
->removeFocusListener(this);
126 mxParentWindow
= nullptr;
127 mxParentCanvas
= nullptr;
131 mxParentWindow
= rxPane
->getWindow();
132 mxParentCanvas
= rxPane
->getCanvas();
136 mxParentWindow
= nullptr;
139 if (mxParentWindow
.is())
141 mxParentWindow
->addWindowListener(this);
142 mxParentWindow
->addPaintListener(this);
143 mxParentWindow
->addMouseListener(this);
144 mxParentWindow
->addFocusListener(this);
146 // We paint our own background, make that of the parent window transparent.
147 Reference
<awt::XWindowPeer
> xPeer (mxParentWindow
, UNO_QUERY
);
149 xPeer
->setBackground(util::Color(0xff000000));
153 void PresenterWindowManager::SetTheme (const std::shared_ptr
<PresenterTheme
>& rpTheme
)
157 // Get background bitmap or background color from the theme.
159 if (mpTheme
.get() != nullptr)
161 mpBackgroundBitmap
= mpTheme
->GetBitmap(OUString(), "Background");
165 void PresenterWindowManager::NotifyViewCreation (const Reference
<XView
>& rxView
)
167 PresenterPaneContainer::SharedPaneDescriptor
pDescriptor (
168 mpPaneContainer
->FindPaneId(rxView
->getResourceId()->getAnchor()));
169 OSL_ASSERT(pDescriptor
.get() != nullptr);
170 if (pDescriptor
.get() != nullptr)
174 mpPresenterController
->GetPaintManager()->Invalidate(
175 pDescriptor
->mxContentWindow
,
176 sal_Int16(awt::InvalidateStyle::TRANSPARENT
177 | awt::InvalidateStyle::CHILDREN
));
181 void PresenterWindowManager::SetPanePosSizeAbsolute (
182 const OUString
& rsPaneURL
,
186 const double nHeight
)
188 PresenterPaneContainer::SharedPaneDescriptor
pDescriptor (
189 mpPaneContainer
->FindPaneURL(rsPaneURL
));
190 if (pDescriptor
.get() != nullptr)
192 if (pDescriptor
->mxBorderWindow
.is())
193 pDescriptor
->mxBorderWindow
->setPosSize(
194 ::sal::static_int_cast
<sal_Int32
>(nX
),
195 ::sal::static_int_cast
<sal_Int32
>(nY
),
196 ::sal::static_int_cast
<sal_Int32
>(nWidth
),
197 ::sal::static_int_cast
<sal_Int32
>(nHeight
),
198 awt::PosSize::POSSIZE
);
202 void PresenterWindowManager::SetPaneBorderPainter (
203 const ::rtl::Reference
<PresenterPaneBorderPainter
>& rPainter
)
205 mpPaneBorderPainter
= rPainter
;
208 //----- XWindowListener -------------------------------------------------------
210 void SAL_CALL
PresenterWindowManager::windowResized (const awt::WindowEvent
& rEvent
)
213 if (rEvent
.Source
== mxParentWindow
)
219 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(mxParentWindow
);
230 void SAL_CALL
PresenterWindowManager::windowMoved (const awt::WindowEvent
& rEvent
)
233 if (rEvent
.Source
!= mxParentWindow
)
235 Reference
<awt::XWindow
> xWindow (rEvent
.Source
,UNO_QUERY
);
236 UpdateWindowSize(xWindow
);
238 // Make sure the background of a transparent window is painted.
239 mpPresenterController
->GetPaintManager()->Invalidate(xWindow
);
243 void SAL_CALL
PresenterWindowManager::windowShown (const lang::EventObject
&) {}
245 void SAL_CALL
PresenterWindowManager::windowHidden (const lang::EventObject
&) {}
247 //----- XPaintListener --------------------------------------------------------
249 void SAL_CALL
PresenterWindowManager::windowPaint (const awt::PaintEvent
& rEvent
)
253 if ( ! mxParentWindow
.is())
255 if ( ! mxParentCanvas
.is())
258 if (mpTheme
.get()!=nullptr)
262 if (mbIsLayoutPending
)
264 PaintBackground(rEvent
.UpdateRect
);
265 PaintChildren(rEvent
);
267 catch (RuntimeException
&)
269 OSL_FAIL("paint failed!");
274 //----- XMouseListener --------------------------------------------------------
276 void SAL_CALL
PresenterWindowManager::mousePressed (const css::awt::MouseEvent
&)
278 mbIsMouseClickPending
= true;
281 void SAL_CALL
PresenterWindowManager::mouseReleased (const css::awt::MouseEvent
& rEvent
)
283 if (mbIsMouseClickPending
)
285 mbIsMouseClickPending
= false;
286 mpPresenterController
->HandleMouseClick(rEvent
);
290 void SAL_CALL
PresenterWindowManager::mouseEntered (const css::awt::MouseEvent
&)
292 mbIsMouseClickPending
= false;
295 void SAL_CALL
PresenterWindowManager::mouseExited (const css::awt::MouseEvent
&)
297 mbIsMouseClickPending
= false;
300 //----- XFocusListener --------------------------------------------------------
302 void SAL_CALL
PresenterWindowManager::focusGained (const css::awt::FocusEvent
& /*rEvent*/)
307 void SAL_CALL
PresenterWindowManager::focusLost (const css::awt::FocusEvent
&)
312 //----- XEventListener --------------------------------------------------------
314 void SAL_CALL
PresenterWindowManager::disposing (const lang::EventObject
& rEvent
)
316 if (rEvent
.Source
== mxParentWindow
)
317 mxParentWindow
= nullptr;
321 void PresenterWindowManager::PaintChildren (const awt::PaintEvent
& rEvent
) const
323 // Call windowPaint on all children that lie in or touch the
325 PresenterPaneContainer::PaneList::const_iterator iPane
;
326 PresenterPaneContainer::PaneList::const_iterator
iEnd (mpPaneContainer
->maPanes
.end());
327 for (iPane
=mpPaneContainer
->maPanes
.begin(); iPane
!=iEnd
; ++iPane
)
331 // Make sure that the pane shall and can be painted.
332 if ( ! (*iPane
)->mbIsActive
)
334 if ((*iPane
)->mbIsSprite
)
336 if ( ! (*iPane
)->mxPane
.is())
338 if ( ! (*iPane
)->mxBorderWindow
.is())
340 Reference
<awt::XWindow
> xBorderWindow ((*iPane
)->mxBorderWindow
);
341 if ( ! xBorderWindow
.is())
344 // Get the area in which the border of the pane has to be painted.
345 const awt::Rectangle
aBorderBox (xBorderWindow
->getPosSize());
346 const awt::Rectangle
aBorderUpdateBox(
347 PresenterGeometryHelper::Intersection(
350 if (aBorderUpdateBox
.Width
<=0 || aBorderUpdateBox
.Height
<=0)
353 const awt::Rectangle
aLocalBorderUpdateBox(
354 PresenterGeometryHelper::TranslateRectangle(
359 // Invalidate the area of the content window.
360 mpPresenterController
->GetPaintManager()->Invalidate(
362 aLocalBorderUpdateBox
,
363 sal_Int16(awt::InvalidateStyle::CHILDREN
364 | awt::InvalidateStyle::NOTRANSPARENT
));
366 catch (RuntimeException
&)
368 OSL_FAIL("paint children failed!");
373 void PresenterWindowManager::SetLayoutMode (const LayoutMode eMode
)
375 OSL_ASSERT(mpPresenterController
.get() != nullptr);
377 if (meLayoutMode
!= eMode
378 || mbIsSlideSorterActive
379 || mbIsHelpViewActive
)
381 meLayoutMode
= eMode
;
382 mbIsSlideSorterActive
= false;
383 mbIsHelpViewActive
= false;
385 mpPresenterController
->RequestViews(
386 mbIsSlideSorterActive
,
387 meLayoutMode
==LM_Notes
,
390 NotifyLayoutModeChange();
394 void PresenterWindowManager::SetSlideSorterState (bool bIsActive
)
396 if (mbIsSlideSorterActive
!= bIsActive
)
398 mbIsSlideSorterActive
= bIsActive
;
399 if (mbIsSlideSorterActive
)
400 mbIsHelpViewActive
= false;
401 StoreViewMode(GetViewMode());
403 mpPresenterController
->RequestViews(
404 mbIsSlideSorterActive
,
405 meLayoutMode
==LM_Notes
,
408 NotifyLayoutModeChange();
412 void PresenterWindowManager::SetHelpViewState (bool bIsActive
)
414 if (mbIsHelpViewActive
!= bIsActive
)
416 mbIsHelpViewActive
= bIsActive
;
417 if (mbIsHelpViewActive
)
418 mbIsSlideSorterActive
= false;
419 StoreViewMode(GetViewMode());
421 mpPresenterController
->RequestViews(
422 mbIsSlideSorterActive
,
423 meLayoutMode
==LM_Notes
,
426 NotifyLayoutModeChange();
430 void PresenterWindowManager::SetViewMode (const ViewMode eMode
)
435 SetSlideSorterState(false);
436 SetHelpViewState(false);
437 SetLayoutMode(LM_Standard
);
441 SetSlideSorterState(false);
442 SetHelpViewState(false);
443 SetLayoutMode(LM_Notes
);
446 case VM_SlideOverview
:
447 SetHelpViewState(false);
448 SetSlideSorterState(true);
452 SetHelpViewState(true);
453 SetSlideSorterState(false);
457 StoreViewMode(eMode
);
460 PresenterWindowManager::ViewMode
PresenterWindowManager::GetViewMode() const
462 if (mbIsHelpViewActive
)
464 else if (mbIsSlideSorterActive
)
465 return VM_SlideOverview
;
466 else if (meLayoutMode
== LM_Notes
)
472 void PresenterWindowManager::RestoreViewMode()
475 PresenterConfigurationAccess
aConfiguration (
477 "/org.openoffice.Office.PresenterScreen/",
478 PresenterConfigurationAccess::READ_ONLY
);
479 aConfiguration
.GetConfigurationNode("Presenter/InitialViewMode") >>= nMode
;
484 SetViewMode(VM_Standard
);
488 SetViewMode(VM_Notes
);
492 SetViewMode(VM_SlideOverview
);
497 void PresenterWindowManager::StoreViewMode (const ViewMode eViewMode
)
501 PresenterConfigurationAccess
aConfiguration (
503 "/org.openoffice.Office.PresenterScreen/",
504 PresenterConfigurationAccess::READ_WRITE
);
505 aConfiguration
.GoToChild(OUString("Presenter"));
511 aValue
<<= sal_Int32(0);
515 aValue
<<= sal_Int32(1);
518 case VM_SlideOverview
:
519 aValue
<<= sal_Int32(2);
523 aConfiguration
.SetProperty ("InitialViewMode", aValue
);
524 aConfiguration
.CommitChanges();
531 void PresenterWindowManager::AddLayoutListener (
532 const Reference
<document::XEventListener
>& rxListener
)
534 maLayoutListeners
.push_back(rxListener
);
537 void PresenterWindowManager::RemoveLayoutListener (
538 const Reference
<document::XEventListener
>& rxListener
)
540 LayoutListenerContainer::iterator
iListener (maLayoutListeners
.begin());
541 LayoutListenerContainer::iterator
iEnd (maLayoutListeners
.end());
542 for ( ; iListener
!=iEnd
; ++iListener
)
544 if (*iListener
== rxListener
)
546 maLayoutListeners
.erase(iListener
);
547 // Assume that there are no multiple entries.
553 void PresenterWindowManager::Layout()
555 if (mxParentWindow
.is() && ! mbIsLayouting
)
557 mbIsLayoutPending
= false;
558 mbIsLayouting
= true;
559 mxScaledBackgroundBitmap
= nullptr;
560 mxClipPolygon
= nullptr;
564 if (mbIsSlideSorterActive
)
565 LayoutSlideSorterMode();
566 else if (mbIsHelpViewActive
)
569 switch (meLayoutMode
)
573 LayoutStandardMode();
587 mbIsLayouting
= false;
591 void PresenterWindowManager::LayoutStandardMode()
593 awt::Rectangle aBox
= mxParentWindow
->getPosSize();
595 const double nGoldenRatio ((1 + sqrt(5.0)) / 2);
596 const double nGap (20);
597 const double nHorizontalSlideDivide (aBox
.Width
/ nGoldenRatio
);
598 double nSlidePreviewTop (0);
601 // For the current slide view calculate the outer height from the outer
602 // width. This takes into account the slide aspect ratio and thus has to
603 // go over the inner pane size.
604 PresenterPaneContainer::SharedPaneDescriptor
pPane (
605 mpPaneContainer
->FindPaneURL(PresenterPaneFactory::msCurrentSlidePreviewPaneURL
));
606 if (pPane
.get() != nullptr)
608 const awt::Size
aCurrentSlideOuterBox(CalculatePaneSize(
609 nHorizontalSlideDivide
- 1.5*nGap
,
610 PresenterPaneFactory::msCurrentSlidePreviewPaneURL
));
611 nSlidePreviewTop
= (aBox
.Height
- aCurrentSlideOuterBox
.Height
) / 2;
613 /// check whether RTL interface or not
614 if(AllSettings::GetLayoutRTL())
615 Temp
=aBox
.Width
- aCurrentSlideOuterBox
.Width
- nGap
;
616 SetPanePosSizeAbsolute (
617 PresenterPaneFactory::msCurrentSlidePreviewPaneURL
,
620 aCurrentSlideOuterBox
.Width
,
621 aCurrentSlideOuterBox
.Height
);
624 // For the next slide view calculate the outer height from the outer
625 // width. This takes into account the slide aspect ratio and thus has to
626 // go over the inner pane size.
627 pPane
= mpPaneContainer
->FindPaneURL(PresenterPaneFactory::msNextSlidePreviewPaneURL
);
628 if (pPane
.get() != nullptr)
630 const awt::Size
aNextSlideOuterBox (CalculatePaneSize(
631 aBox
.Width
- nHorizontalSlideDivide
- 1.5*nGap
,
632 PresenterPaneFactory::msNextSlidePreviewPaneURL
));
633 double Temp
=aBox
.Width
- aNextSlideOuterBox
.Width
- nGap
;
634 /// check whether RTL interface or not
635 if(AllSettings::GetLayoutRTL())
637 SetPanePosSizeAbsolute (
638 PresenterPaneFactory::msNextSlidePreviewPaneURL
,
641 aNextSlideOuterBox
.Width
,
642 aNextSlideOuterBox
.Height
);
648 void PresenterWindowManager::LayoutNotesMode()
650 awt::Rectangle aBox
= mxParentWindow
->getPosSize();
652 const geometry::RealRectangle2D
aToolBarBox (LayoutToolBar());
654 const double nGoldenRatio ((1 + sqrt(5.0)) / 2);
655 const double nGap (20);
656 const double nPrimaryWidth (aBox
.Width
/ nGoldenRatio
);
657 const double nSecondaryWidth (aBox
.Width
- nPrimaryWidth
);
658 const double nTertiaryWidth (nSecondaryWidth
/ nGoldenRatio
);
659 double nSlidePreviewTop (0);
660 double nNotesViewBottom (aToolBarBox
.Y1
- nGap
);
661 /// check whether RTL interface or not
664 // The notes view has no fixed aspect ratio.
665 PresenterPaneContainer::SharedPaneDescriptor
pPane (
666 mpPaneContainer
->FindPaneURL(PresenterPaneFactory::msNotesPaneURL
));
667 if (pPane
.get() != nullptr)
669 const geometry::RealSize2D
aNotesViewOuterSize(
670 nPrimaryWidth
- 1.5*nGap
+ 0.5,
672 nSlidePreviewTop
= (aBox
.Height
673 - aToolBarBox
.Y2
+ aToolBarBox
.Y1
- aNotesViewOuterSize
.Height
) / 2;
674 /// check whether RTL interface or not
675 double Temp
=aBox
.Width
- aNotesViewOuterSize
.Width
- nGap
;
676 if(AllSettings::GetLayoutRTL())
678 SetPanePosSizeAbsolute (
679 PresenterPaneFactory::msNotesPaneURL
,
682 aNotesViewOuterSize
.Width
,
683 aNotesViewOuterSize
.Height
);
684 nNotesViewBottom
= nSlidePreviewTop
+ aNotesViewOuterSize
.Height
;
687 // For the current slide view calculate the outer height from the outer
688 // width. This takes into account the slide aspect ratio and thus has to
689 // go over the inner pane size.
690 pPane
= mpPaneContainer
->FindPaneURL(PresenterPaneFactory::msCurrentSlidePreviewPaneURL
);
691 if (pPane
.get() != nullptr)
693 const awt::Size
aCurrentSlideOuterBox(CalculatePaneSize(
694 nSecondaryWidth
- 1.5*nGap
,
695 PresenterPaneFactory::msCurrentSlidePreviewPaneURL
));
696 /// check whether RTL interface or not
698 if(AllSettings::GetLayoutRTL())
699 Temp
=aBox
.Width
- aCurrentSlideOuterBox
.Width
- nGap
;
700 SetPanePosSizeAbsolute (
701 PresenterPaneFactory::msCurrentSlidePreviewPaneURL
,
704 aCurrentSlideOuterBox
.Width
,
705 aCurrentSlideOuterBox
.Height
);
708 // For the next slide view calculate the outer height from the outer
709 // width. This takes into account the slide aspect ratio and thus has to
710 // go over the inner pane size.
711 pPane
= mpPaneContainer
->FindPaneURL(PresenterPaneFactory::msNextSlidePreviewPaneURL
);
712 if (pPane
.get() != nullptr)
714 const awt::Size
aNextSlideOuterBox (CalculatePaneSize(
716 PresenterPaneFactory::msNextSlidePreviewPaneURL
));
717 /// check whether RTL interface or not
719 if(AllSettings::GetLayoutRTL())
720 Temp
=aBox
.Width
- aNextSlideOuterBox
.Width
- nGap
;
721 SetPanePosSizeAbsolute (
722 PresenterPaneFactory::msNextSlidePreviewPaneURL
,
724 nNotesViewBottom
- aNextSlideOuterBox
.Height
,
725 aNextSlideOuterBox
.Width
,
726 aNextSlideOuterBox
.Height
);
732 void PresenterWindowManager::LayoutSlideSorterMode()
734 const geometry::RealRectangle2D
aToolBarBox (LayoutToolBar());
736 awt::Rectangle aWindowBox
= mxParentWindow
->getPosSize();
737 const double nGap (20);
738 SetPanePosSizeAbsolute(
739 mpPaneContainer
->GetPaneURLForViewURL(PresenterViewFactory::msSlideSorterURL
),
742 aWindowBox
.Width
- 2*nGap
,
743 aToolBarBox
.Y1
- 2*nGap
);
746 void PresenterWindowManager::LayoutHelpMode()
748 const geometry::RealRectangle2D
aToolBarBox (LayoutToolBar());
750 awt::Rectangle aWindowBox
= mxParentWindow
->getPosSize();
751 const double nGap (20);
752 const double nGoldenRatio ((1 + sqrt(5.0)) / 2);
753 const double nWidth
= ::std::min(aWindowBox
.Width
- 2*nGap
, aWindowBox
.Width
/nGoldenRatio
);
754 SetPanePosSizeAbsolute(
755 mpPaneContainer
->GetPaneURLForViewURL(PresenterViewFactory::msHelpViewURL
),
756 (aWindowBox
.Width
- nWidth
)/2,
759 aToolBarBox
.Y1
- 2*nGap
);
762 geometry::RealRectangle2D
PresenterWindowManager::LayoutToolBar()
764 double nToolBarWidth (400);
765 double nToolBarHeight (80);
767 // Get access to the tool bar.
768 PresenterPaneContainer::SharedPaneDescriptor
pDescriptor(
769 mpPaneContainer
->FindPaneURL(PresenterPaneFactory::msToolBarPaneURL
));
770 if (pDescriptor
.get() != nullptr)
772 PresenterToolBarView
* pToolBarView
773 = dynamic_cast<PresenterToolBarView
*>(pDescriptor
->mxView
.get());
774 if (pToolBarView
!= nullptr && pToolBarView
->GetPresenterToolBar().is())
776 geometry::RealSize2D
aSize (pToolBarView
->GetPresenterToolBar()->GetMinimalSize());
778 if (mpPaneBorderPainter
.is())
780 const awt::Rectangle
aBox (mpPaneBorderPainter
->addBorder (
781 PresenterPaneFactory::msToolBarPaneURL
,
785 PresenterGeometryHelper::Round(aSize
.Width
),
786 PresenterGeometryHelper::Round(aSize
.Height
)),
787 css::drawing::framework::BorderType_TOTAL_BORDER
));
789 nToolBarWidth
= aBox
.Width
;
790 nToolBarHeight
= aBox
.Height
;
794 nToolBarWidth
= aSize
.Width
+ 20;
795 nToolBarHeight
= aSize
.Height
+ 10;
800 const awt::Rectangle aBox
= mxParentWindow
->getPosSize();
801 const double nToolBarX ((aBox
.Width
- nToolBarWidth
) / 2);
802 const double nToolBarY (aBox
.Height
- nToolBarHeight
);
803 SetPanePosSizeAbsolute(
804 PresenterPaneFactory::msToolBarPaneURL
,
810 return geometry::RealRectangle2D(
813 nToolBarX
+ nToolBarWidth
- 1,
814 nToolBarY
+ nToolBarHeight
- 1);
817 awt::Size
PresenterWindowManager::CalculatePaneSize (
818 const double nOuterWidth
,
819 const OUString
& rsPaneURL
)
821 // Calculate the inner width by removing the pane border.
822 awt::Rectangle
aInnerBox (mpPaneBorderPainter
->RemoveBorder (
825 sal_Int32(nOuterWidth
+0.5),sal_Int32(nOuterWidth
)),
826 drawing::framework::BorderType_TOTAL_BORDER
));
828 // Calculate the inner height with the help of the slide aspect ratio.
829 const double nCurrentSlideInnerHeight (
830 aInnerBox
.Width
/ mpPresenterController
->GetSlideAspectRatio());
832 // Add the pane border to get the outer box.
833 awt::Rectangle
aOuterBox (mpPaneBorderPainter
->AddBorder (
836 aInnerBox
.Width
,sal_Int32(nCurrentSlideInnerHeight
+0.5)),
837 drawing::framework::BorderType_TOTAL_BORDER
));
839 return awt::Size(aOuterBox
.Width
, aOuterBox
.Height
);
842 void PresenterWindowManager::NotifyLayoutModeChange()
844 document::EventObject aEvent
;
845 aEvent
.Source
= Reference
<XInterface
>(static_cast<XWeak
*>(this));
847 LayoutListenerContainer
aContainerCopy (maLayoutListeners
);
848 LayoutListenerContainer::iterator
iListener (aContainerCopy
.begin());
849 LayoutListenerContainer::iterator
iEnd (aContainerCopy
.end());
850 for ( ; iListener
!=iEnd
; ++iListener
)
856 (*iListener
)->notifyEvent(aEvent
);
858 catch (lang::DisposedException
&)
860 RemoveLayoutListener(*iListener
);
862 catch (RuntimeException
&)
869 void PresenterWindowManager::NotifyDisposing()
871 lang::EventObject aEvent
;
872 aEvent
.Source
= static_cast<XWeak
*>(this);
874 LayoutListenerContainer aContainer
;
875 aContainer
.swap(maLayoutListeners
);
876 LayoutListenerContainer::iterator
iListener (aContainer
.begin());
877 LayoutListenerContainer::iterator
iEnd (aContainer
.end());
878 for ( ; iListener
!=iEnd
; ++iListener
)
884 (*iListener
)->disposing(aEvent
);
886 catch (lang::DisposedException
&)
889 catch (RuntimeException
&)
896 void PresenterWindowManager::UpdateWindowSize (const Reference
<awt::XWindow
>& rxBorderWindow
)
898 PresenterPaneContainer::SharedPaneDescriptor
pDescriptor (
899 mpPaneContainer
->FindBorderWindow(rxBorderWindow
));
900 if (pDescriptor
.get() != nullptr)
902 mxClipPolygon
= nullptr;
904 // ToTop is called last because it may invalidate the iterator.
905 if ( ! mbIsLayouting
)
906 mpPaneContainer
->ToTop(pDescriptor
);
910 void PresenterWindowManager::PaintBackground (const awt::Rectangle
& rUpdateBox
)
912 if ( ! mxParentWindow
.is())
915 Reference
<rendering::XGraphicDevice
> xDevice (mxParentCanvas
->getDevice());
919 // Create a polygon for the background and for clipping.
920 Reference
<rendering::XPolyPolygon2D
> xBackgroundPolygon (
921 PresenterGeometryHelper::CreatePolygon(mxParentWindow
->getPosSize(), xDevice
));
922 if ( ! mxClipPolygon
.is())
923 mxClipPolygon
= CreateClipPolyPolygon();
925 // Create View- and RenderState structs.
926 const rendering::ViewState
aViewState(
927 geometry::AffineMatrix2D(1,0,0, 0,1,0),
928 PresenterGeometryHelper::CreatePolygon(rUpdateBox
, xDevice
));
929 rendering::RenderState
aRenderState (
930 geometry::AffineMatrix2D(1,0,0, 0,1,0),
933 rendering::CompositeOperation::SOURCE
);
935 // Paint the background.
936 if (mpBackgroundBitmap
.get() != nullptr)
938 ProvideBackgroundBitmap();
940 if (mxScaledBackgroundBitmap
.is())
942 Sequence
<rendering::Texture
> aTextures (1);
943 const geometry::IntegerSize2D
aBitmapSize(mxScaledBackgroundBitmap
->getSize());
944 aTextures
[0] = rendering::Texture (
945 geometry::AffineMatrix2D(
946 aBitmapSize
.Width
,0,0,
947 0,aBitmapSize
.Height
,0),
950 mxScaledBackgroundBitmap
,
953 rendering::StrokeAttributes(),
954 rendering::TexturingMode::REPEAT
,
955 rendering::TexturingMode::REPEAT
);
957 mxParentCanvas
->fillTexturedPolyPolygon(
965 const util::Color
aBackgroundColor (mpBackgroundBitmap
->maReplacementColor
);
966 aRenderState
.DeviceColor
[0] = ((aBackgroundColor
>> 16) & 0x0ff) / 255.0;
967 aRenderState
.DeviceColor
[1] = ((aBackgroundColor
>> 8) & 0x0ff) / 255.0;
968 aRenderState
.DeviceColor
[2] = ((aBackgroundColor
>> 0) & 0x0ff) / 255.0;
969 aRenderState
.DeviceColor
[3] = ((aBackgroundColor
>> 24) & 0x0ff) / 255.0;
970 mxParentCanvas
->fillPolyPolygon(
978 void PresenterWindowManager::ProvideBackgroundBitmap()
980 if ( ! mxScaledBackgroundBitmap
.is())
982 Reference
<rendering::XBitmap
> xBitmap (mpBackgroundBitmap
->GetNormalBitmap());
985 const bool bStretchVertical (mpBackgroundBitmap
->meVerticalTexturingMode
986 == PresenterBitmapDescriptor::Stretch
);
987 const bool bStretchHorizontal (mpBackgroundBitmap
->meHorizontalTexturingMode
988 == PresenterBitmapDescriptor::Stretch
);
989 if (bStretchHorizontal
|| bStretchVertical
)
991 geometry::RealSize2D aSize
;
992 if (bStretchVertical
)
993 aSize
.Height
= mxParentWindow
->getPosSize().Height
;
995 aSize
.Height
= xBitmap
->getSize().Height
;
996 if (bStretchHorizontal
)
997 aSize
.Width
= mxParentWindow
->getPosSize().Width
;
999 aSize
.Width
= xBitmap
->getSize().Width
;
1000 mxScaledBackgroundBitmap
= xBitmap
->getScaledBitmap(aSize
, false);
1004 mxScaledBackgroundBitmap
.set(xBitmap
, UNO_QUERY
);
1010 Reference
<rendering::XPolyPolygon2D
> PresenterWindowManager::CreateClipPolyPolygon() const
1012 // Create a clip polygon that includes the whole update area but has the
1013 // content windows as holes.
1014 const sal_Int32
nPaneCount (mpPaneContainer
->maPanes
.size());
1015 ::std::vector
<awt::Rectangle
> aRectangles
;
1016 aRectangles
.reserve(1+nPaneCount
);
1017 aRectangles
.push_back(mxParentWindow
->getPosSize());
1018 PresenterPaneContainer::PaneList::const_iterator iPane
;
1019 PresenterPaneContainer::PaneList::const_iterator
iEnd (mpPaneContainer
->maPanes
.end());
1020 for (iPane
=mpPaneContainer
->maPanes
.begin(); iPane
!=iEnd
; ++iPane
)
1022 PresenterPaneContainer::SharedPaneDescriptor
pDescriptor (*iPane
);
1023 if ( ! pDescriptor
->mbIsActive
)
1025 if ( ! pDescriptor
->mbIsOpaque
)
1027 if ( ! pDescriptor
->mxBorderWindow
.is() || ! pDescriptor
->mxContentWindow
.is())
1029 Reference
<awt::XWindow2
> xWindow (pDescriptor
->mxBorderWindow
, UNO_QUERY
);
1030 if (xWindow
.is() && ! xWindow
->isVisible())
1033 const awt::Rectangle
aOuterBorderBox (pDescriptor
->mxBorderWindow
->getPosSize());
1034 awt::Rectangle
aInnerBorderBox (pDescriptor
->mxContentWindow
->getPosSize());
1035 aInnerBorderBox
.X
+= aOuterBorderBox
.X
;
1036 aInnerBorderBox
.Y
+= aOuterBorderBox
.Y
;
1037 aRectangles
.push_back(aInnerBorderBox
);
1039 Reference
<rendering::XPolyPolygon2D
> xPolyPolygon (
1040 PresenterGeometryHelper::CreatePolygon(
1042 mxParentCanvas
->getDevice()));
1043 if (xPolyPolygon
.is())
1044 xPolyPolygon
->setFillRule(rendering::FillRule_EVEN_ODD
);
1045 return xPolyPolygon
;
1048 void PresenterWindowManager::Update()
1050 mxClipPolygon
= nullptr;
1051 mbIsLayoutPending
= true;
1053 mpPresenterController
->GetPaintManager()->Invalidate(mxParentWindow
);
1056 void PresenterWindowManager::ThrowIfDisposed() const
1058 if (rBHelper
.bDisposed
|| rBHelper
.bInDispose
)
1060 throw lang::DisposedException (
1061 "PresenterWindowManager has already been disposed",
1062 const_cast<uno::XWeak
*>(static_cast<const uno::XWeak
*>(this)));
1066 } } // end of namespace ::sdext::presenter
1068 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */