fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / sdext / source / presenter / PresenterWindowManager.cxx
blob0fce6117345b345b6020ab0a838a605c5273691b
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 #undef ENABLE_PANE_RESIZING
21 //#define ENABLE_PANE_RESIZING
23 #include "vcl/svapp.hxx"
24 #include "vcl/settings.hxx"
25 #include "PresenterWindowManager.hxx"
26 #include "PresenterController.hxx"
27 #include "PresenterGeometryHelper.hxx"
28 #include "PresenterHelper.hxx"
29 #include "PresenterPaintManager.hxx"
30 #include "PresenterPaneBase.hxx"
31 #include "PresenterPaneBorderManager.hxx"
32 #include "PresenterPaneBorderPainter.hxx"
33 #include "PresenterPaneContainer.hxx"
34 #include "PresenterPaneFactory.hxx"
35 #include "PresenterSprite.hxx"
36 #include "PresenterToolBar.hxx"
37 #include "PresenterViewFactory.hxx"
38 #include "PresenterTheme.hxx"
39 #include <com/sun/star/awt/InvalidateStyle.hpp>
40 #include <com/sun/star/awt/PosSize.hpp>
41 #include <com/sun/star/awt/SystemPointer.hpp>
42 #include <com/sun/star/awt/XDevice.hpp>
43 #include <com/sun/star/awt/XWindow2.hpp>
44 #include <com/sun/star/awt/XWindowPeer.hpp>
45 #include <com/sun/star/awt/WindowAttribute.hpp>
46 #include <com/sun/star/container/XChild.hpp>
47 #include <com/sun/star/drawing/framework/ResourceId.hpp>
48 #include <com/sun/star/rendering/CompositeOperation.hpp>
49 #include <com/sun/star/rendering/FillRule.hpp>
50 #include <com/sun/star/rendering/PathCapType.hpp>
51 #include <com/sun/star/rendering/PathJoinType.hpp>
52 #include <com/sun/star/rendering/Texture.hpp>
53 #include <com/sun/star/rendering/TexturingMode.hpp>
54 #include <com/sun/star/rendering/XSpriteCanvas.hpp>
55 #include <math.h>
57 using namespace ::com::sun::star;
58 using namespace ::com::sun::star::uno;
59 using namespace ::com::sun::star::drawing::framework;
61 namespace sdext { namespace presenter {
63 //===== PresenterWindowManager ================================================
65 PresenterWindowManager::PresenterWindowManager (
66 const Reference<XComponentContext>& rxContext,
67 const ::rtl::Reference<PresenterPaneContainer>& rpPaneContainer,
68 const ::rtl::Reference<PresenterController>& rpPresenterController)
69 : PresenterWindowManagerInterfaceBase(m_aMutex),
70 mxComponentContext(rxContext),
71 mpPresenterController(rpPresenterController),
72 mxParentWindow(),
73 mxParentCanvas(),
74 mxPaneBorderManager(),
75 mpPaneBorderPainter(),
76 mpPaneContainer(rpPaneContainer),
77 mbIsLayoutPending(true),
78 mbIsLayouting(false),
79 mpTheme(),
80 mpBackgroundBitmap(),
81 mxScaledBackgroundBitmap(),
82 maPaneBackgroundColor(),
83 mxClipPolygon(),
84 meLayoutMode(LM_Generic),
85 mbIsSlideSorterActive(false),
86 mbIsHelpViewActive(false),
87 maLayoutListeners(),
88 mbIsMouseClickPending(false)
90 UpdateWindowList();
93 PresenterWindowManager::~PresenterWindowManager()
97 void SAL_CALL PresenterWindowManager::disposing()
99 NotifyDisposing();
101 SetParentPane(NULL);
103 Reference<lang::XComponent> xComponent (mxPaneBorderManager, UNO_QUERY);
104 if (xComponent.is())
105 xComponent->dispose();
106 mxPaneBorderManager = NULL;
108 PresenterPaneContainer::PaneList::const_iterator iPane;
109 PresenterPaneContainer::PaneList::const_iterator iEnd (mpPaneContainer->maPanes.end());
110 for (iPane=mpPaneContainer->maPanes.begin(); iPane!=iEnd; ++iPane)
112 if ((*iPane)->mxBorderWindow.is())
114 (*iPane)->mxBorderWindow->removeWindowListener(this);
115 (*iPane)->mxBorderWindow->removeFocusListener(this);
116 #ifndef ENABLE_PANE_RESIZING
117 (*iPane)->mxBorderWindow->removeMouseListener(this);
118 #endif
123 void PresenterWindowManager::SetParentPane (
124 const Reference<drawing::framework::XPane>& rxPane)
126 if (mxParentWindow.is())
128 mxParentWindow->removeWindowListener(this);
129 mxParentWindow->removePaintListener(this);
130 mxParentWindow->removeMouseListener(this);
131 mxParentWindow->removeFocusListener(this);
133 mxParentWindow = NULL;
134 mxParentCanvas = NULL;
136 if (rxPane.is())
138 mxParentWindow = rxPane->getWindow();
139 mxParentCanvas = rxPane->getCanvas();
141 else
143 mxParentWindow = NULL;
146 if (mxParentWindow.is())
148 mxParentWindow->addWindowListener(this);
149 mxParentWindow->addPaintListener(this);
150 mxParentWindow->addMouseListener(this);
151 mxParentWindow->addFocusListener(this);
153 // We paint our own background, make that of the parent window transparent.
154 Reference<awt::XWindowPeer> xPeer (mxParentWindow, UNO_QUERY);
155 if (xPeer.is())
156 xPeer->setBackground(util::Color(0xff000000));
160 void PresenterWindowManager::SetTheme (const ::boost::shared_ptr<PresenterTheme>& rpTheme)
162 mpTheme = rpTheme;
164 // Get background bitmap or background color from the theme.
166 if (mpTheme.get() != NULL)
168 mpBackgroundBitmap = mpTheme->GetBitmap(OUString(), "Background");
172 void PresenterWindowManager::NotifyViewCreation (const Reference<XView>& rxView)
174 PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
175 mpPaneContainer->FindPaneId(rxView->getResourceId()->getAnchor()));
176 OSL_ASSERT(pDescriptor.get() != NULL);
177 if (pDescriptor.get() != NULL)
179 Layout();
181 mpPresenterController->GetPaintManager()->Invalidate(
182 pDescriptor->mxContentWindow,
183 (sal_Int16)(awt::InvalidateStyle::TRANSPARENT
184 | awt::InvalidateStyle::CHILDREN));
188 void PresenterWindowManager::SetPanePosSizeAbsolute (
189 const OUString& rsPaneURL,
190 const double nX,
191 const double nY,
192 const double nWidth,
193 const double nHeight)
195 PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
196 mpPaneContainer->FindPaneURL(rsPaneURL));
197 if (pDescriptor.get() != NULL)
199 awt::Rectangle aParentBox = mxParentWindow->getPosSize();
200 if (aParentBox.Width > 0 && aParentBox.Height > 0)
202 pDescriptor->mnLeft = nX / aParentBox.Width;
203 pDescriptor->mnTop = nY / aParentBox.Height;
204 pDescriptor->mnRight = (nX + nWidth) / aParentBox.Width;
205 pDescriptor->mnBottom = (nY + nHeight) / aParentBox.Height;
207 if (pDescriptor->mxBorderWindow.is())
208 pDescriptor->mxBorderWindow->setPosSize(
209 ::sal::static_int_cast<sal_Int32>(nX),
210 ::sal::static_int_cast<sal_Int32>(nY),
211 ::sal::static_int_cast<sal_Int32>(nWidth),
212 ::sal::static_int_cast<sal_Int32>(nHeight),
213 awt::PosSize::POSSIZE);
217 void PresenterWindowManager::SetPaneBorderPainter (
218 const ::rtl::Reference<PresenterPaneBorderPainter>& rPainter)
220 mpPaneBorderPainter = rPainter;
223 //----- XWindowListener -------------------------------------------------------
225 void SAL_CALL PresenterWindowManager::windowResized (const awt::WindowEvent& rEvent)
226 throw (RuntimeException, std::exception)
228 ThrowIfDisposed();
229 if (rEvent.Source == mxParentWindow)
231 Layout();
233 else
235 Reference<awt::XWindow> xWindow (rEvent.Source,UNO_QUERY);
236 if (xWindow.is())
238 UpdateWindowSize(xWindow);
240 // Make sure the background of a transparent window is painted.
241 mpPresenterController->GetPaintManager()->Invalidate(mxParentWindow);
246 void SAL_CALL PresenterWindowManager::windowMoved (const awt::WindowEvent& rEvent)
247 throw (RuntimeException, std::exception)
249 ThrowIfDisposed();
250 if (rEvent.Source != mxParentWindow)
252 Reference<awt::XWindow> xWindow (rEvent.Source,UNO_QUERY);
253 UpdateWindowSize(xWindow);
255 // Make sure the background of a transparent window is painted.
256 mpPresenterController->GetPaintManager()->Invalidate(xWindow);
260 void SAL_CALL PresenterWindowManager::windowShown (const lang::EventObject& rEvent)
261 throw (RuntimeException, std::exception)
263 (void)rEvent;
266 void SAL_CALL PresenterWindowManager::windowHidden (const lang::EventObject& rEvent)
267 throw (RuntimeException, std::exception)
269 (void)rEvent;
272 //----- XPaintListener --------------------------------------------------------
274 void SAL_CALL PresenterWindowManager::windowPaint (const awt::PaintEvent& rEvent)
275 throw (RuntimeException, std::exception)
277 ThrowIfDisposed();
279 if ( ! mxParentWindow.is())
280 return;
281 if ( ! mxParentCanvas.is())
282 return;
284 if (mpTheme.get()!=NULL)
288 if (mbIsLayoutPending)
289 Layout();
290 PaintBackground(rEvent.UpdateRect);
291 if ( ! PaintChildren(rEvent))
293 Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxParentCanvas, UNO_QUERY);
294 // if (xSpriteCanvas.is())
295 // xSpriteCanvas->updateScreen(sal_False);
298 catch (RuntimeException&)
300 OSL_FAIL("paint failed!");
305 //----- XMouseListener --------------------------------------------------------
307 void SAL_CALL PresenterWindowManager::mousePressed (const css::awt::MouseEvent& rEvent)
308 throw(css::uno::RuntimeException, std::exception)
310 (void)rEvent;
311 mbIsMouseClickPending = true;
314 void SAL_CALL PresenterWindowManager::mouseReleased (const css::awt::MouseEvent& rEvent)
315 throw(css::uno::RuntimeException, std::exception)
317 #ifndef ENABLE_PANE_RESIZING
318 if (mbIsMouseClickPending)
320 mbIsMouseClickPending = false;
321 mpPresenterController->HandleMouseClick(rEvent);
323 #else
324 (void)rEvent;
325 #endif
328 void SAL_CALL PresenterWindowManager::mouseEntered (const css::awt::MouseEvent& rEvent)
329 throw(css::uno::RuntimeException, std::exception)
331 (void)rEvent;
332 mbIsMouseClickPending = false;
335 void SAL_CALL PresenterWindowManager::mouseExited (const css::awt::MouseEvent& rEvent)
336 throw(css::uno::RuntimeException, std::exception)
338 (void)rEvent;
339 mbIsMouseClickPending = false;
342 //----- XFocusListener --------------------------------------------------------
344 void SAL_CALL PresenterWindowManager::focusGained (const css::awt::FocusEvent& rEvent)
345 throw (css::uno::RuntimeException, std::exception)
347 ThrowIfDisposed();
348 (void)rEvent;
349 OSL_TRACE("PresenterWindowManager::focusGained window %p\n",
350 rEvent.Source.get());
353 void SAL_CALL PresenterWindowManager::focusLost (const css::awt::FocusEvent& rEvent)
354 throw (css::uno::RuntimeException, std::exception)
356 ThrowIfDisposed();
357 (void)rEvent;
360 //----- XEventListener --------------------------------------------------------
362 void SAL_CALL PresenterWindowManager::disposing (const lang::EventObject& rEvent)
363 throw (RuntimeException, std::exception)
365 if (rEvent.Source == mxParentWindow)
366 mxParentWindow = NULL;
367 else
369 Reference<awt::XWindow> xWindow (rEvent.Source, UNO_QUERY);
375 bool PresenterWindowManager::PaintChildren (const awt::PaintEvent& rEvent) const
377 bool bChildInvalidated (false);
379 // Call windowPaint on all children that lie in or touch the
380 // update rectangle.
381 PresenterPaneContainer::PaneList::const_iterator iPane;
382 PresenterPaneContainer::PaneList::const_iterator iEnd (mpPaneContainer->maPanes.end());
383 for (iPane=mpPaneContainer->maPanes.begin(); iPane!=iEnd; ++iPane)
387 // Make sure that the pane shall and can be painted.
388 if ( ! (*iPane)->mbIsActive)
389 continue;
390 if ((*iPane)->mbIsSprite)
391 continue;
392 if ( ! (*iPane)->mxPane.is())
393 continue;
394 if ( ! (*iPane)->mxBorderWindow.is())
395 continue;
396 Reference<awt::XWindow> xBorderWindow ((*iPane)->mxBorderWindow);
397 if ( ! xBorderWindow.is())
398 continue;
400 // Get the area in which the border of the pane has to be painted.
401 const awt::Rectangle aBorderBox (xBorderWindow->getPosSize());
402 const awt::Rectangle aBorderUpdateBox(
403 PresenterGeometryHelper::Intersection(
404 rEvent.UpdateRect,
405 aBorderBox));
406 if (aBorderUpdateBox.Width<=0 || aBorderUpdateBox.Height<=0)
407 continue;
409 const awt::Rectangle aLocalBorderUpdateBox(
410 PresenterGeometryHelper::TranslateRectangle(
411 aBorderUpdateBox,
412 -aBorderBox.X,
413 -aBorderBox.Y));
415 // Invalidate the area of the content window.
416 mpPresenterController->GetPaintManager()->Invalidate(
417 xBorderWindow,
418 aLocalBorderUpdateBox,
419 sal_Int16(awt::InvalidateStyle::CHILDREN
420 | awt::InvalidateStyle::NOTRANSPARENT));
422 catch (RuntimeException&)
424 OSL_FAIL("paint children failed!");
428 return bChildInvalidated;
431 void PresenterWindowManager::SetLayoutMode (const LayoutMode eMode)
433 OSL_ASSERT(mpPresenterController.get() != NULL);
435 if (meLayoutMode != eMode
436 || mbIsSlideSorterActive
437 || mbIsHelpViewActive)
439 meLayoutMode = eMode;
440 mbIsSlideSorterActive = false;
441 mbIsHelpViewActive = false;
443 mpPresenterController->RequestViews(
444 mbIsSlideSorterActive,
445 meLayoutMode==LM_Notes,
446 mbIsHelpViewActive);
447 Layout();
448 NotifyLayoutModeChange();
452 void PresenterWindowManager::SetSlideSorterState (bool bIsActive)
454 if (mbIsSlideSorterActive != bIsActive)
456 mbIsSlideSorterActive = bIsActive;
457 if (mbIsSlideSorterActive)
458 mbIsHelpViewActive = false;
459 StoreViewMode(GetViewMode());
461 mpPresenterController->RequestViews(
462 mbIsSlideSorterActive,
463 meLayoutMode==LM_Notes,
464 mbIsHelpViewActive);
465 Layout();
466 NotifyLayoutModeChange();
470 void PresenterWindowManager::SetHelpViewState (bool bIsActive)
472 if (mbIsHelpViewActive != bIsActive)
474 mbIsHelpViewActive = bIsActive;
475 if (mbIsHelpViewActive)
476 mbIsSlideSorterActive = false;
477 StoreViewMode(GetViewMode());
479 mpPresenterController->RequestViews(
480 mbIsSlideSorterActive,
481 meLayoutMode==LM_Notes,
482 mbIsHelpViewActive);
483 Layout();
484 NotifyLayoutModeChange();
488 void PresenterWindowManager::SetViewMode (const ViewMode eMode)
490 switch (eMode)
492 case VM_Standard:
493 SetSlideSorterState(false);
494 SetHelpViewState(false);
495 SetLayoutMode(LM_Standard);
496 break;
498 case VM_Notes:
499 SetSlideSorterState(false);
500 SetHelpViewState(false);
501 SetLayoutMode(LM_Notes);
502 break;
504 case VM_SlideOverview:
505 SetHelpViewState(false);
506 SetSlideSorterState(true);
507 break;
509 case VM_Help:
510 SetHelpViewState(true);
511 SetSlideSorterState(false);
512 break;
515 StoreViewMode(eMode);
518 PresenterWindowManager::ViewMode PresenterWindowManager::GetViewMode() const
520 if (mbIsHelpViewActive)
521 return VM_Help;
522 else if (mbIsSlideSorterActive)
523 return VM_SlideOverview;
524 else if (meLayoutMode == LM_Notes)
525 return VM_Notes;
526 else
527 return VM_Standard;
530 void PresenterWindowManager::RestoreViewMode()
532 sal_Int32 nMode (0);
533 PresenterConfigurationAccess aConfiguration (
534 mxComponentContext,
535 OUString("/org.openoffice.Office.PresenterScreen/"),
536 PresenterConfigurationAccess::READ_ONLY);
537 aConfiguration.GetConfigurationNode("Presenter/InitialViewMode") >>= nMode;
538 switch (nMode)
540 default:
541 case 0:
542 SetViewMode(VM_Standard);
543 break;
545 case 1:
546 SetViewMode(VM_Notes);
547 break;
549 case 2:
550 SetViewMode(VM_SlideOverview);
551 break;
555 void PresenterWindowManager::StoreViewMode (const ViewMode eViewMode)
559 PresenterConfigurationAccess aConfiguration (
560 mxComponentContext,
561 OUString("/org.openoffice.Office.PresenterScreen/"),
562 PresenterConfigurationAccess::READ_WRITE);
563 aConfiguration.GoToChild(OUString("Presenter"));
564 Any aValue;
565 switch (eViewMode)
567 default:
568 case VM_Standard:
569 aValue = Any(sal_Int32(0));
570 break;
572 case VM_Notes:
573 aValue = Any(sal_Int32(1));
574 break;
576 case VM_SlideOverview:
577 aValue = Any(sal_Int32(2));
578 break;
581 aConfiguration.SetProperty ("InitialViewMode", aValue);
582 aConfiguration.CommitChanges();
584 catch (Exception&)
589 void PresenterWindowManager::AddLayoutListener (
590 const Reference<document::XEventListener>& rxListener)
592 maLayoutListeners.push_back(rxListener);
595 void PresenterWindowManager::RemoveLayoutListener (
596 const Reference<document::XEventListener>& rxListener)
598 LayoutListenerContainer::iterator iListener (maLayoutListeners.begin());
599 LayoutListenerContainer::iterator iEnd (maLayoutListeners.end());
600 for ( ; iListener!=iEnd; ++iListener)
602 if (*iListener == rxListener)
604 maLayoutListeners.erase(iListener);
605 // Assume that there are no multiple entries.
606 break;
611 void PresenterWindowManager::Layout()
613 if (mxParentWindow.is() && ! mbIsLayouting)
615 mbIsLayoutPending = false;
616 mbIsLayouting = true;
617 mxScaledBackgroundBitmap = NULL;
618 mxClipPolygon = NULL;
622 if (mbIsSlideSorterActive)
623 LayoutSlideSorterMode();
624 else if (mbIsHelpViewActive)
625 LayoutHelpMode();
626 else
627 switch (meLayoutMode)
629 case LM_Standard:
630 default:
631 LayoutStandardMode();
632 break;
634 case LM_Notes:
635 LayoutNotesMode();
636 break;
639 catch (Exception&)
641 OSL_ASSERT(false);
642 throw;
645 mbIsLayouting = false;
649 void PresenterWindowManager::LayoutStandardMode()
651 awt::Rectangle aBox = mxParentWindow->getPosSize();
653 const double nGoldenRatio ((1 + sqrt(5.0)) / 2);
654 const double nGap (20);
655 const double nHorizontalSlideDivide (aBox.Width / nGoldenRatio);
656 double nSlidePreviewTop (0);
659 // For the current slide view calculate the outer height from the outer
660 // width. This takes into acount the slide aspect ratio and thus has to
661 // go over the inner pane size.
662 PresenterPaneContainer::SharedPaneDescriptor pPane (
663 mpPaneContainer->FindPaneURL(PresenterPaneFactory::msCurrentSlidePreviewPaneURL));
664 if (pPane.get() != NULL)
666 const awt::Size aCurrentSlideOuterBox(CalculatePaneSize(
667 nHorizontalSlideDivide - 1.5*nGap,
668 PresenterPaneFactory::msCurrentSlidePreviewPaneURL));
669 nSlidePreviewTop = (aBox.Height - aCurrentSlideOuterBox.Height) / 2;
670 double Temp=nGap;
671 /// check whether RTL interface or not
672 if(AllSettings::GetLayoutRTL())
673 Temp=aBox.Width - aCurrentSlideOuterBox.Width - nGap;
674 SetPanePosSizeAbsolute (
675 PresenterPaneFactory::msCurrentSlidePreviewPaneURL,
676 Temp,
677 nSlidePreviewTop,
678 aCurrentSlideOuterBox.Width,
679 aCurrentSlideOuterBox.Height);
682 // For the next slide view calculate the outer height from the outer
683 // width. This takes into acount the slide aspect ratio and thus has to
684 // go over the inner pane size.
685 pPane = mpPaneContainer->FindPaneURL(PresenterPaneFactory::msNextSlidePreviewPaneURL);
686 if (pPane.get() != NULL)
688 const awt::Size aNextSlideOuterBox (CalculatePaneSize(
689 aBox.Width - nHorizontalSlideDivide - 1.5*nGap,
690 PresenterPaneFactory::msNextSlidePreviewPaneURL));
691 double Temp=aBox.Width - aNextSlideOuterBox.Width - nGap;
692 /// check whether RTL interface or not
693 if(AllSettings::GetLayoutRTL())
694 Temp=nGap;
695 SetPanePosSizeAbsolute (
696 PresenterPaneFactory::msNextSlidePreviewPaneURL,
697 Temp,
698 nSlidePreviewTop,
699 aNextSlideOuterBox.Width,
700 aNextSlideOuterBox.Height);
703 LayoutToolBar();
706 void PresenterWindowManager::LayoutNotesMode()
708 awt::Rectangle aBox = mxParentWindow->getPosSize();
710 const geometry::RealRectangle2D aToolBarBox (LayoutToolBar());
712 const double nGoldenRatio ((1 + sqrt(5.0)) / 2);
713 const double nGap (20);
714 const double nPrimaryWidth (aBox.Width / nGoldenRatio);
715 const double nSecondaryWidth (aBox.Width - nPrimaryWidth);
716 const double nTertiaryWidth (nSecondaryWidth / nGoldenRatio);
717 double nSlidePreviewTop (0);
718 double nNotesViewBottom (aToolBarBox.Y1 - nGap);
719 /// check whether RTL interface or not
722 // The notes view has no fixed aspect ratio.
723 PresenterPaneContainer::SharedPaneDescriptor pPane (
724 mpPaneContainer->FindPaneURL(PresenterPaneFactory::msNotesPaneURL));
725 if (pPane.get() != NULL)
727 const geometry::RealSize2D aNotesViewOuterSize(
728 nPrimaryWidth - 1.5*nGap + 0.5,
729 nNotesViewBottom);
730 nSlidePreviewTop = (aBox.Height
731 - aToolBarBox.Y2 + aToolBarBox.Y1 - aNotesViewOuterSize.Height) / 2;
732 /// check whether RTL interface or not
733 double Temp=aBox.Width - aNotesViewOuterSize.Width - nGap;
734 if(AllSettings::GetLayoutRTL())
735 Temp=nGap;
736 SetPanePosSizeAbsolute (
737 PresenterPaneFactory::msNotesPaneURL,
738 Temp,
739 nSlidePreviewTop,
740 aNotesViewOuterSize.Width,
741 aNotesViewOuterSize.Height);
742 nNotesViewBottom = nSlidePreviewTop + aNotesViewOuterSize.Height;
745 // For the current slide view calculate the outer height from the outer
746 // width. This takes into acount the slide aspect ratio and thus has to
747 // go over the inner pane size.
748 pPane = mpPaneContainer->FindPaneURL(PresenterPaneFactory::msCurrentSlidePreviewPaneURL);
749 if (pPane.get() != NULL)
751 const awt::Size aCurrentSlideOuterBox(CalculatePaneSize(
752 nSecondaryWidth - 1.5*nGap,
753 PresenterPaneFactory::msCurrentSlidePreviewPaneURL));
754 /// check whether RTL interface or not
755 double Temp=nGap;
756 if(AllSettings::GetLayoutRTL())
757 Temp=aBox.Width - aCurrentSlideOuterBox.Width - nGap;
758 SetPanePosSizeAbsolute (
759 PresenterPaneFactory::msCurrentSlidePreviewPaneURL,
760 Temp,
761 nSlidePreviewTop,
762 aCurrentSlideOuterBox.Width,
763 aCurrentSlideOuterBox.Height);
766 // For the next slide view calculate the outer height from the outer
767 // width. This takes into acount the slide aspect ratio and thus has to
768 // go over the inner pane size.
769 pPane = mpPaneContainer->FindPaneURL(PresenterPaneFactory::msNextSlidePreviewPaneURL);
770 if (pPane.get() != NULL)
772 const awt::Size aNextSlideOuterBox (CalculatePaneSize(
773 nTertiaryWidth,
774 PresenterPaneFactory::msNextSlidePreviewPaneURL));
775 /// check whether RTL interface or not
776 double Temp=nGap;
777 if(AllSettings::GetLayoutRTL())
778 Temp=aBox.Width - aNextSlideOuterBox.Width - nGap;
779 SetPanePosSizeAbsolute (
780 PresenterPaneFactory::msNextSlidePreviewPaneURL,
781 Temp,
782 nNotesViewBottom - aNextSlideOuterBox.Height,
783 aNextSlideOuterBox.Width,
784 aNextSlideOuterBox.Height);
791 void PresenterWindowManager::LayoutSlideSorterMode()
793 const geometry::RealRectangle2D aToolBarBox (LayoutToolBar());
795 awt::Rectangle aWindowBox = mxParentWindow->getPosSize();
796 const double nGap (20);
797 SetPanePosSizeAbsolute(
798 mpPaneContainer->GetPaneURLForViewURL(PresenterViewFactory::msSlideSorterURL),
799 nGap,
800 nGap,
801 aWindowBox.Width - 2*nGap,
802 aToolBarBox.Y1 - 2*nGap);
805 void PresenterWindowManager::LayoutHelpMode()
807 const geometry::RealRectangle2D aToolBarBox (LayoutToolBar());
809 awt::Rectangle aWindowBox = mxParentWindow->getPosSize();
810 const double nGap (20);
811 const double nGoldenRatio ((1 + sqrt(5.0)) / 2);
812 const double nWidth = ::std::min(aWindowBox.Width - 2*nGap, aWindowBox.Width/nGoldenRatio);
813 SetPanePosSizeAbsolute(
814 mpPaneContainer->GetPaneURLForViewURL(PresenterViewFactory::msHelpViewURL),
815 (aWindowBox.Width - nWidth)/2,
816 nGap,
817 nWidth,
818 aToolBarBox.Y1 - 2*nGap);
821 geometry::RealRectangle2D PresenterWindowManager::LayoutToolBar()
823 double nToolBarWidth (400);
824 double nToolBarHeight (80);
826 // Get access to the tool bar.
827 PresenterPaneContainer::SharedPaneDescriptor pDescriptor(
828 mpPaneContainer->FindPaneURL(PresenterPaneFactory::msToolBarPaneURL));
829 if (pDescriptor.get() != NULL)
831 PresenterToolBarView* pToolBarView
832 = dynamic_cast<PresenterToolBarView*>(pDescriptor->mxView.get());
833 if (pToolBarView != NULL && pToolBarView->GetPresenterToolBar().is())
835 geometry::RealSize2D aSize (pToolBarView->GetPresenterToolBar()->GetMinimalSize());
837 if (mpPaneBorderPainter.is())
839 const awt::Rectangle aBox (mpPaneBorderPainter->addBorder (
840 PresenterPaneFactory::msToolBarPaneURL,
841 awt::Rectangle(
844 PresenterGeometryHelper::Round(aSize.Width),
845 PresenterGeometryHelper::Round(aSize.Height)),
846 css::drawing::framework::BorderType_TOTAL_BORDER));
848 nToolBarWidth = aBox.Width;
849 nToolBarHeight = aBox.Height;
851 else
853 nToolBarWidth = aSize.Width + 20;
854 nToolBarHeight = aSize.Height + 10;
859 const awt::Rectangle aBox = mxParentWindow->getPosSize();
860 const double nToolBarX ((aBox.Width - nToolBarWidth) / 2);
861 const double nToolBarY (aBox.Height - nToolBarHeight);
862 SetPanePosSizeAbsolute(
863 PresenterPaneFactory::msToolBarPaneURL,
864 nToolBarX,
865 nToolBarY,
866 nToolBarWidth,
867 nToolBarHeight);
869 return geometry::RealRectangle2D(
870 nToolBarX,
871 nToolBarY,
872 nToolBarX + nToolBarWidth - 1,
873 nToolBarY + nToolBarHeight - 1);
876 awt::Size PresenterWindowManager::CalculatePaneSize (
877 const double nOuterWidth,
878 const OUString& rsPaneURL)
880 // Calculate the inner width by removing the pane border.
881 awt::Rectangle aInnerBox (mpPaneBorderPainter->RemoveBorder (
882 rsPaneURL,
883 awt::Rectangle(0,0,
884 sal_Int32(nOuterWidth+0.5),sal_Int32(nOuterWidth)),
885 drawing::framework::BorderType_TOTAL_BORDER));
887 // Calculate the inner height with the help of the slide aspect ratio.
888 const double nCurrentSlideInnerHeight (
889 aInnerBox.Width / mpPresenterController->GetSlideAspectRatio());
891 // Add the pane border to get the outer box.
892 awt::Rectangle aOuterBox (mpPaneBorderPainter->AddBorder (
893 rsPaneURL,
894 awt::Rectangle(0,0,
895 aInnerBox.Width,sal_Int32(nCurrentSlideInnerHeight+0.5)),
896 drawing::framework::BorderType_TOTAL_BORDER));
898 return awt::Size(aOuterBox.Width, aOuterBox.Height);
901 void PresenterWindowManager::NotifyLayoutModeChange()
903 document::EventObject aEvent;
904 aEvent.Source = Reference<XInterface>(static_cast<XWeak*>(this));
906 LayoutListenerContainer aContainerCopy (maLayoutListeners);
907 LayoutListenerContainer::iterator iListener (aContainerCopy.begin());
908 LayoutListenerContainer::iterator iEnd (aContainerCopy.end());
909 for ( ; iListener!=iEnd; ++iListener)
911 if (iListener->is())
915 (*iListener)->notifyEvent(aEvent);
917 catch (lang::DisposedException&)
919 RemoveLayoutListener(*iListener);
921 catch (RuntimeException&)
928 void PresenterWindowManager::NotifyDisposing()
930 lang::EventObject aEvent;
931 aEvent.Source = static_cast<XWeak*>(this);
933 LayoutListenerContainer aContainer;
934 aContainer.swap(maLayoutListeners);
935 LayoutListenerContainer::iterator iListener (aContainer.begin());
936 LayoutListenerContainer::iterator iEnd (aContainer.end());
937 for ( ; iListener!=iEnd; ++iListener)
939 if (iListener->is())
943 (*iListener)->disposing(aEvent);
945 catch (lang::DisposedException&)
948 catch (RuntimeException&)
955 void PresenterWindowManager::UpdateWindowSize (const Reference<awt::XWindow>& rxBorderWindow)
957 PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
958 mpPaneContainer->FindBorderWindow(rxBorderWindow));
959 if (pDescriptor.get() != NULL)
961 mxClipPolygon = NULL;
963 awt::Rectangle aParentBox = mxParentWindow->getPosSize();
964 awt::Rectangle aBorderBox (pDescriptor->mxBorderWindow->getPosSize());
966 if ( ! mbIsLayouting)
968 const double nWidth (aParentBox.Width);
969 const double nHeight (aParentBox.Height);
970 pDescriptor->mnLeft = double(aBorderBox.X) / nWidth;
971 pDescriptor->mnTop = double(aBorderBox.Y) / nHeight;
972 pDescriptor->mnRight = double(aBorderBox.X + aBorderBox.Width) / nWidth;
973 pDescriptor->mnBottom = double(aBorderBox.Y + aBorderBox.Height) / nHeight;
975 else
977 // This update of the window size was initiated by
978 // Layout(). Therefore the window size does not have to be
979 // updated.
982 // ToTop is called last because it may invalidate the iterator.
983 if ( ! mbIsLayouting)
984 mpPaneContainer->ToTop(pDescriptor);
988 void PresenterWindowManager::PaintBackground (const awt::Rectangle& rUpdateBox)
990 (void)rUpdateBox;
991 if ( ! mxParentWindow.is())
992 return;
994 Reference<rendering::XGraphicDevice> xDevice (mxParentCanvas->getDevice());
995 if ( ! xDevice.is())
996 return;
998 // Create a polygon for the background and for clipping.
999 Reference<rendering::XPolyPolygon2D> xBackgroundPolygon (
1000 PresenterGeometryHelper::CreatePolygon(mxParentWindow->getPosSize(), xDevice));
1001 if ( ! mxClipPolygon.is())
1002 mxClipPolygon = CreateClipPolyPolygon();
1004 // Create View- and RenderState structs.
1005 const rendering::ViewState aViewState(
1006 geometry::AffineMatrix2D(1,0,0, 0,1,0),
1007 PresenterGeometryHelper::CreatePolygon(rUpdateBox, xDevice));
1008 rendering::RenderState aRenderState (
1009 geometry::AffineMatrix2D(1,0,0, 0,1,0),
1010 mxClipPolygon,
1011 Sequence<double>(4),
1012 rendering::CompositeOperation::SOURCE);
1014 // Paint the background.
1015 if (mpBackgroundBitmap.get() != NULL)
1017 ProvideBackgroundBitmap();
1019 if (mxScaledBackgroundBitmap.is())
1021 Sequence<rendering::Texture> aTextures (1);
1022 const geometry::IntegerSize2D aBitmapSize(mxScaledBackgroundBitmap->getSize());
1023 aTextures[0] = rendering::Texture (
1024 geometry::AffineMatrix2D(
1025 aBitmapSize.Width,0,0,
1026 0,aBitmapSize.Height,0),
1029 mxScaledBackgroundBitmap,
1030 NULL,
1031 NULL,
1032 rendering::StrokeAttributes(),
1033 rendering::TexturingMode::REPEAT,
1034 rendering::TexturingMode::REPEAT);
1036 mxParentCanvas->fillTexturedPolyPolygon(
1037 xBackgroundPolygon,
1038 aViewState,
1039 aRenderState,
1040 aTextures);
1042 else
1044 const util::Color aBackgroundColor (mpBackgroundBitmap->maReplacementColor);
1045 aRenderState.DeviceColor[0] = ((aBackgroundColor >> 16) & 0x0ff) / 255.0;
1046 aRenderState.DeviceColor[1] = ((aBackgroundColor >> 8) & 0x0ff) / 255.0;
1047 aRenderState.DeviceColor[2] = ((aBackgroundColor >> 0) & 0x0ff) / 255.0;
1048 aRenderState.DeviceColor[3] = ((aBackgroundColor >> 24) & 0x0ff) / 255.0;
1049 mxParentCanvas->fillPolyPolygon(
1050 xBackgroundPolygon,
1051 aViewState,
1052 aRenderState);
1057 void PresenterWindowManager::ProvideBackgroundBitmap()
1059 if ( ! mxScaledBackgroundBitmap.is())
1061 Reference<rendering::XBitmap> xBitmap (mpBackgroundBitmap->GetNormalBitmap());
1062 if (xBitmap.is())
1064 const bool bStretchVertical (mpBackgroundBitmap->meVerticalTexturingMode
1065 == PresenterBitmapDescriptor::Stretch);
1066 const bool bStretchHorizontal (mpBackgroundBitmap->meHorizontalTexturingMode
1067 == PresenterBitmapDescriptor::Stretch);
1068 if (bStretchHorizontal || bStretchVertical)
1070 geometry::RealSize2D aSize;
1071 if (bStretchVertical)
1072 aSize.Height = mxParentWindow->getPosSize().Height;
1073 else
1074 aSize.Height = xBitmap->getSize().Height;
1075 if (bStretchHorizontal)
1076 aSize.Width = mxParentWindow->getPosSize().Width;
1077 else
1078 aSize.Width = xBitmap->getSize().Width;
1079 mxScaledBackgroundBitmap = xBitmap->getScaledBitmap(aSize, sal_False);
1081 else
1083 mxScaledBackgroundBitmap
1084 = Reference<rendering::XBitmap>(xBitmap, UNO_QUERY);
1090 Reference<rendering::XPolyPolygon2D> PresenterWindowManager::CreateClipPolyPolygon() const
1092 // Create a clip polygon that includes the whole update area but has the
1093 // content windows as holes.
1094 const sal_Int32 nPaneCount (mpPaneContainer->maPanes.size());
1095 ::std::vector<awt::Rectangle> aRectangles;
1096 aRectangles.reserve(1+nPaneCount);
1097 aRectangles.push_back(mxParentWindow->getPosSize());
1098 PresenterPaneContainer::PaneList::const_iterator iPane;
1099 PresenterPaneContainer::PaneList::const_iterator iEnd (mpPaneContainer->maPanes.end());
1100 for (iPane=mpPaneContainer->maPanes.begin(); iPane!=iEnd; ++iPane)
1102 PresenterPaneContainer::SharedPaneDescriptor pDescriptor (*iPane);
1103 if ( ! pDescriptor->mbIsActive)
1104 continue;
1105 if ( ! pDescriptor->mbIsOpaque)
1106 continue;
1107 if ( ! pDescriptor->mxBorderWindow.is() || ! pDescriptor->mxContentWindow.is())
1108 continue;
1109 Reference<awt::XWindow2> xWindow (pDescriptor->mxBorderWindow, UNO_QUERY);
1110 if (xWindow.is() && ! xWindow->isVisible())
1111 continue;
1113 const awt::Rectangle aOuterBorderBox (pDescriptor->mxBorderWindow->getPosSize());
1114 awt::Rectangle aInnerBorderBox (pDescriptor->mxContentWindow->getPosSize());
1115 aInnerBorderBox.X += aOuterBorderBox.X;
1116 aInnerBorderBox.Y += aOuterBorderBox.Y;
1117 aRectangles.push_back(aInnerBorderBox);
1119 Reference<rendering::XPolyPolygon2D> xPolyPolygon (
1120 PresenterGeometryHelper::CreatePolygon(
1121 aRectangles,
1122 mxParentCanvas->getDevice()));
1123 if (xPolyPolygon.is())
1124 xPolyPolygon->setFillRule(rendering::FillRule_EVEN_ODD);
1125 return xPolyPolygon;
1128 void PresenterWindowManager::UpdateWindowList()
1130 #ifdef ENABLE_PANE_RESIZING
1133 OSL_ASSERT(mxComponentContext.is());
1135 Reference<lang::XComponent> xComponent (mxPaneBorderManager, UNO_QUERY);
1136 if (xComponent.is())
1137 xComponent->dispose();
1139 Reference<lang::XMultiComponentFactory> xFactory (mxComponentContext->getServiceManager());
1140 if (xFactory.is())
1142 Sequence<Any> aArguments (1 + mpPaneContainer->maPanes.size()*2);
1143 sal_Int32 nIndex (0);
1144 aArguments[nIndex++] = Any(mxParentWindow);
1145 for (sal_uInt32 nPaneIndex=0; nPaneIndex<mpPaneContainer->maPanes.size(); ++nPaneIndex)
1147 if ( ! mpPaneContainer->maPanes[nPaneIndex]->mbIsActive)
1148 continue;
1150 const Reference<awt::XWindow> xBorderWindow (
1151 mpPaneContainer->maPanes[nPaneIndex]->mxBorderWindow);
1152 const Reference<awt::XWindow> xContentWindow (
1153 mpPaneContainer->maPanes[nPaneIndex]->mxContentWindow);
1154 const Reference<awt::XWindow2> xBorderWindow2(xBorderWindow, UNO_QUERY);
1155 if (xBorderWindow.is()
1156 && xContentWindow.is()
1157 && ( ! xBorderWindow2.is() || xBorderWindow2->isVisible()))
1159 aArguments[nIndex++] = Any(xBorderWindow);
1160 aArguments[nIndex++] = Any(xContentWindow);
1164 aArguments.realloc(nIndex);
1165 rtl::Reference<PresenterPaneBorderManager> pManager (
1166 new PresenterPaneBorderManager (
1167 mxComponentContext,
1168 mpPresenterController));
1169 pManager->initialize(aArguments);
1170 mxPaneBorderManager = Reference<XInterface>(static_cast<XWeak*>(pManager.get()));
1173 catch (RuntimeException&)
1176 #endif
1179 void PresenterWindowManager::Invalidate()
1181 mpPresenterController->GetPaintManager()->Invalidate(mxParentWindow);
1183 void PresenterWindowManager::Update()
1185 mxClipPolygon = NULL;
1186 mbIsLayoutPending = true;
1188 UpdateWindowList();
1189 Invalidate();
1192 void PresenterWindowManager::ThrowIfDisposed() const
1193 throw (::com::sun::star::lang::DisposedException)
1195 if (rBHelper.bDisposed || rBHelper.bInDispose)
1197 throw lang::DisposedException (
1198 "PresenterWindowManager has already been disposed",
1199 const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
1203 } } // end of namespace ::sdext::presenter
1205 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */