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"
23 #include "PresenterSlideSorter.hxx"
24 #include "PresenterButton.hxx"
25 #include "PresenterCanvasHelper.hxx"
26 #include "PresenterGeometryHelper.hxx"
27 #include "PresenterHelper.hxx"
28 #include "PresenterPaintManager.hxx"
29 #include "PresenterPaneBase.hxx"
30 #include "PresenterScrollBar.hxx"
31 #include "PresenterUIPainter.hxx"
32 #include "PresenterWindowManager.hxx"
33 #include <com/sun/star/awt/PosSize.hpp>
34 #include <com/sun/star/awt/XWindowPeer.hpp>
35 #include <com/sun/star/container/XNameAccess.hpp>
36 #include <com/sun/star/container/XNamed.hpp>
37 #include <com/sun/star/drawing/XSlideSorterBase.hpp>
38 #include <com/sun/star/drawing/framework/XConfigurationController.hpp>
39 #include <com/sun/star/drawing/framework/XControllerManager.hpp>
40 #include <com/sun/star/rendering/XBitmapCanvas.hpp>
41 #include <com/sun/star/rendering/CompositeOperation.hpp>
42 #include <com/sun/star/rendering/TextDirection.hpp>
43 #include <com/sun/star/rendering/XPolyPolygon2D.hpp>
44 #include <com/sun/star/util/Color.hpp>
47 #include <boost/bind.hpp>
49 using namespace ::com::sun::star
;
50 using namespace ::com::sun::star::uno
;
51 using namespace ::com::sun::star::drawing::framework
;
54 const static sal_Int32
gnVerticalGap (10);
55 const static sal_Int32
gnVerticalBorder (10);
56 const static sal_Int32
gnHorizontalGap (10);
57 const static sal_Int32
gnHorizontalBorder (10);
59 const static double gnMinimalPreviewWidth (200);
60 const static double gnPreferredPreviewWidth (300);
61 const static double gnMaximalPreviewWidth (400);
62 const static sal_Int32
gnPreferredColumnCount (6);
63 const static double gnMinimalHorizontalPreviewGap(15);
64 const static double gnPreferredHorizontalPreviewGap(25);
65 const static double gnMaximalHorizontalPreviewGap(50);
66 const static double gnPreferredVerticalPreviewGap(25);
68 const static sal_Int32
gnHorizontalLabelBorder (3);
69 const static sal_Int32
gnHorizontalLabelPadding (5);
71 const static sal_Int32
gnVerticalButtonPadding (gnVerticalGap
);
74 namespace sdext
{ namespace presenter
{
77 sal_Int32
round (const double nValue
) { return sal::static_int_cast
<sal_Int32
>(0.5 + nValue
); }
78 sal_Int32
floor (const double nValue
) { return sal::static_int_cast
<sal_Int32
>(nValue
); }
81 //===== PresenterSlideSorter::Layout ==========================================
83 class PresenterSlideSorter::Layout
86 Layout (const ::rtl::Reference
<PresenterScrollBar
>& rpVerticalScrollBar
);
88 void Update (const geometry::RealRectangle2D
& rBoundingBox
, const double nSlideAspectRatio
);
89 void SetupVisibleArea();
90 void UpdateScrollBars();
91 bool IsScrollBarNeeded (const sal_Int32 nSlideCount
);
92 geometry::RealPoint2D
GetLocalPosition (const geometry::RealPoint2D
& rWindowPoint
) const;
93 geometry::RealPoint2D
GetWindowPosition(const geometry::RealPoint2D
& rLocalPoint
) const;
94 sal_Int32
GetColumn (const geometry::RealPoint2D
& rLocalPoint
,
95 const bool bReturnInvalidValue
= false) const;
96 sal_Int32
GetRow (const geometry::RealPoint2D
& rLocalPoint
,
97 const bool bReturnInvalidValue
= false) const;
98 sal_Int32
GetSlideIndexForPosition (const css::geometry::RealPoint2D
& rPoint
) const;
99 css::geometry::RealPoint2D
GetPoint (
100 const sal_Int32 nSlideIndex
,
101 const sal_Int32 nRelativeHorizontalPosition
,
102 const sal_Int32 nRelativeVerticalPosition
) const;
103 css::awt::Rectangle
GetBoundingBox (const sal_Int32 nSlideIndex
) const;
104 void ForAllVisibleSlides (const ::boost::function
<void(sal_Int32
)>& rAction
);
105 sal_Int32
GetFirstVisibleSlideIndex() const;
106 sal_Int32
GetLastVisibleSlideIndex() const;
107 bool SetHorizontalOffset (const double nOffset
);
108 bool SetVerticalOffset (const double nOffset
);
110 css::geometry::RealRectangle2D maBoundingBox
;
111 css::geometry::IntegerSize2D maPreviewSize
;
112 sal_Int32 mnHorizontalOffset
;
113 sal_Int32 mnVerticalOffset
;
114 sal_Int32 mnHorizontalGap
;
115 sal_Int32 mnVerticalGap
;
116 sal_Int32 mnHorizontalBorder
;
117 sal_Int32 mnVerticalBorder
;
118 sal_Int32 mnRowCount
;
119 sal_Int32 mnColumnCount
;
120 sal_Int32 mnSlideCount
;
121 sal_Int32 mnSlideIndexAtMouse
;
122 sal_Int32 mnFirstVisibleColumn
;
123 sal_Int32 mnLastVisibleColumn
;
124 sal_Int32 mnFirstVisibleRow
;
125 sal_Int32 mnLastVisibleRow
;
128 ::rtl::Reference
<PresenterScrollBar
> mpVerticalScrollBar
;
130 sal_Int32
GetIndex (const sal_Int32 nRow
, const sal_Int32 nColumn
) const;
131 sal_Int32
GetRow (const sal_Int32 nSlideIndex
) const;
132 sal_Int32
GetColumn (const sal_Int32 nSlideIndex
) const;
135 //==== PresenterSlideSorter::MouseOverManager =================================
137 class PresenterSlideSorter::MouseOverManager
138 : ::boost::noncopyable
142 const Reference
<container::XIndexAccess
>& rxSlides
,
143 const ::boost::shared_ptr
<PresenterTheme
>& rpTheme
,
144 const Reference
<awt::XWindow
>& rxInvalidateTarget
,
145 const ::boost::shared_ptr
<PresenterPaintManager
>& rpPaintManager
);
149 const sal_Int32 nSlideIndex
,
150 const Reference
<rendering::XCanvas
>& rxCanvas
,
151 const Reference
<rendering::XPolyPolygon2D
>& rxClip
);
154 const sal_Int32 nSlideIndex
,
155 const awt::Rectangle
& rBox
);
158 Reference
<rendering::XCanvas
> mxCanvas
;
159 const Reference
<container::XIndexAccess
> mxSlides
;
160 SharedBitmapDescriptor mpLeftLabelBitmap
;
161 SharedBitmapDescriptor mpCenterLabelBitmap
;
162 SharedBitmapDescriptor mpRightLabelBitmap
;
163 PresenterTheme::SharedFontDescriptor mpFont
;
164 sal_Int32 mnSlideIndex
;
165 awt::Rectangle maSlideBoundingBox
;
167 Reference
<rendering::XBitmap
> mxBitmap
;
168 Reference
<awt::XWindow
> mxInvalidateTarget
;
169 ::boost::shared_ptr
<PresenterPaintManager
> mpPaintManager
;
172 const Reference
<rendering::XCanvas
>& rxCanvas
);
173 /** Create a bitmap that shows the given text and is not wider than the
176 Reference
<rendering::XBitmap
> CreateBitmap (
177 const OUString
& rsText
,
178 const sal_Int32 nMaximalWidth
) const;
180 geometry::IntegerSize2D
CalculateLabelSize (
181 const OUString
& rsText
) const;
182 OUString
GetFittingText (const OUString
& rsText
, const double nMaximalWidth
) const;
183 void PaintButtonBackground (
184 const Reference
<rendering::XCanvas
>& rxCanvas
,
185 const geometry::IntegerSize2D
& rSize
) const;
188 //==== PresenterSlideSorter::CurrentSlideFrameRenderer ========================
190 class PresenterSlideSorter::CurrentSlideFrameRenderer
193 CurrentSlideFrameRenderer (
194 const css::uno::Reference
<css::uno::XComponentContext
>& rxContext
,
195 const css::uno::Reference
<css::rendering::XCanvas
>& rxCanvas
);
196 ~CurrentSlideFrameRenderer();
198 void PaintCurrentSlideFrame (
199 const awt::Rectangle
& rSlideBoundingBox
,
200 const Reference
<rendering::XCanvas
>& rxCanvas
,
201 const geometry::RealRectangle2D
& rClipBox
);
203 /** Enlarge the given rectangle to include the current slide indicator.
205 awt::Rectangle
GetBoundingBox (
206 const awt::Rectangle
& rSlideBoundingBox
);
209 SharedBitmapDescriptor mpTopLeft
;
210 SharedBitmapDescriptor mpTop
;
211 SharedBitmapDescriptor mpTopRight
;
212 SharedBitmapDescriptor mpLeft
;
213 SharedBitmapDescriptor mpRight
;
214 SharedBitmapDescriptor mpBottomLeft
;
215 SharedBitmapDescriptor mpBottom
;
216 SharedBitmapDescriptor mpBottomRight
;
217 sal_Int32 mnTopFrameSize
;
218 sal_Int32 mnLeftFrameSize
;
219 sal_Int32 mnRightFrameSize
;
220 sal_Int32 mnBottomFrameSize
;
222 static void PaintBitmapOnce(
223 const css::uno::Reference
<css::rendering::XBitmap
>& rxBitmap
,
224 const css::uno::Reference
<css::rendering::XCanvas
>& rxCanvas
,
225 const Reference
<rendering::XPolyPolygon2D
>& rxClip
,
228 static void PaintBitmapTiled(
229 const css::uno::Reference
<css::rendering::XBitmap
>& rxBitmap
,
230 const css::uno::Reference
<css::rendering::XCanvas
>& rxCanvas
,
231 const geometry::RealRectangle2D
& rClipBox
,
235 const double nHeight
);
238 //===== PresenterSlideSorter ==================================================
240 PresenterSlideSorter::PresenterSlideSorter (
241 const Reference
<uno::XComponentContext
>& rxContext
,
242 const Reference
<XResourceId
>& rxViewId
,
243 const Reference
<frame::XController
>& rxController
,
244 const ::rtl::Reference
<PresenterController
>& rpPresenterController
)
245 : PresenterSlideSorterInterfaceBase(m_aMutex
),
246 mxComponentContext(rxContext
),
251 mpPresenterController(rpPresenterController
),
252 mxSlideShowController(mpPresenterController
->GetSlideShowController()),
254 mbIsPaintPending(true),
255 mbIsLayoutPending(true),
257 mpVerticalScrollBar(),
259 mpMouseOverManager(),
260 mnSlideIndexMousePressed(-1),
261 mnCurrentSlideIndex(-1),
263 maSeparatorColor(0x00ffffff),
264 maCloseButtonCenter(),
265 maCurrentSlideFrameBoundingBox(),
266 mpCurrentSlideFrameRenderer(),
269 if ( ! rxContext
.is()
271 || ! rxController
.is()
272 || rpPresenterController
.get()==NULL
)
274 throw lang::IllegalArgumentException();
277 if ( ! mxSlideShowController
.is())
278 throw RuntimeException();
282 // Get pane and window.
283 Reference
<XControllerManager
> xCM (rxController
, UNO_QUERY_THROW
);
284 Reference
<XConfigurationController
> xCC (
285 xCM
->getConfigurationController(), UNO_QUERY_THROW
);
286 Reference
<lang::XMultiComponentFactory
> xFactory (
287 mxComponentContext
->getServiceManager(), UNO_QUERY_THROW
);
289 mxPane
= Reference
<XPane
>(xCC
->getResource(rxViewId
->getAnchor()), UNO_QUERY_THROW
);
290 mxWindow
= mxPane
->getWindow();
292 // Add window listener.
293 mxWindow
->addWindowListener(this);
294 mxWindow
->addPaintListener(this);
295 mxWindow
->addMouseListener(this);
296 mxWindow
->addMouseMotionListener(this);
297 mxWindow
->setVisible(sal_True
);
299 // Remember the current slide.
300 mnCurrentSlideIndex
= mxSlideShowController
->getCurrentSlideIndex();
302 // Create the scroll bar.
303 mpVerticalScrollBar
= ::rtl::Reference
<PresenterScrollBar
>(
304 new PresenterVerticalScrollBar(
307 mpPresenterController
->GetPaintManager(),
308 ::boost::bind(&PresenterSlideSorter::SetVerticalOffset
,this,_1
)));
310 mpCloseButton
= PresenterButton::Create(
312 mpPresenterController
,
313 mpPresenterController
->GetTheme(),
316 "SlideSorterCloser");
318 if (mpPresenterController
->GetTheme().get() != NULL
)
320 PresenterTheme::SharedFontDescriptor
pFont (
321 mpPresenterController
->GetTheme()->GetFont("ButtonFont"));
322 if (pFont
.get() != NULL
)
323 maSeparatorColor
= pFont
->mnColor
;
326 // Create the layout.
327 mpLayout
.reset(new Layout(mpVerticalScrollBar
));
329 // Create the preview cache.
330 mxPreviewCache
= Reference
<drawing::XSlidePreviewCache
>(
331 xFactory
->createInstanceWithContext(
332 OUString("com.sun.star.drawing.PresenterPreviewCache"),
335 Reference
<container::XIndexAccess
> xSlides (mxSlideShowController
, UNO_QUERY
);
336 mxPreviewCache
->setDocumentSlides(xSlides
, rxController
->getModel());
337 mxPreviewCache
->addPreviewCreationNotifyListener(this);
340 mpLayout
->mnSlideCount
= xSlides
->getCount();
343 // Create the mouse over manager.
344 mpMouseOverManager
.reset(new MouseOverManager(
345 Reference
<container::XIndexAccess
>(mxSlideShowController
, UNO_QUERY
),
346 mpPresenterController
->GetTheme(),
348 mpPresenterController
->GetPaintManager()));
350 // Listen for changes of the current slide.
351 Reference
<beans::XPropertySet
> xControllerProperties (rxController
, UNO_QUERY_THROW
);
352 xControllerProperties
->addPropertyChangeListener(
353 OUString("CurrentPage"),
356 // Move the current slide in the center of the window.
357 const awt::Rectangle
aCurrentSlideBBox (mpLayout
->GetBoundingBox(mnCurrentSlideIndex
));
358 const awt::Rectangle
aWindowBox (mxWindow
->getPosSize());
359 SetHorizontalOffset(aCurrentSlideBBox
.X
- aWindowBox
.Width
/2.0);
361 catch (RuntimeException
&)
368 PresenterSlideSorter::~PresenterSlideSorter()
372 void SAL_CALL
PresenterSlideSorter::disposing()
374 mxComponentContext
= NULL
;
378 if (mpVerticalScrollBar
.is())
380 Reference
<lang::XComponent
> xComponent (
381 static_cast<XWeak
*>(mpVerticalScrollBar
.get()), UNO_QUERY
);
382 mpVerticalScrollBar
= NULL
;
384 xComponent
->dispose();
386 if (mpCloseButton
.is())
388 Reference
<lang::XComponent
> xComponent (
389 static_cast<XWeak
*>(mpCloseButton
.get()), UNO_QUERY
);
390 mpCloseButton
= NULL
;
392 xComponent
->dispose();
397 Reference
<lang::XComponent
> xComponent (mxCanvas
, UNO_QUERY
);
399 xComponent
->removeEventListener(static_cast<awt::XWindowListener
*>(this));
402 mpPresenterController
= NULL
;
403 mxSlideShowController
= NULL
;
405 mpMouseOverManager
.reset();
407 if (mxPreviewCache
.is())
409 mxPreviewCache
->removePreviewCreationNotifyListener(this);
411 Reference
<XComponent
> xComponent (mxPreviewCache
, UNO_QUERY
);
412 mxPreviewCache
= NULL
;
414 xComponent
->dispose();
419 mxWindow
->removeWindowListener(this);
420 mxWindow
->removePaintListener(this);
421 mxWindow
->removeMouseListener(this);
422 mxWindow
->removeMouseMotionListener(this);
426 void PresenterSlideSorter::SetActiveState (const bool bIsActive
)
431 //----- lang::XEventListener --------------------------------------------------
433 void SAL_CALL
PresenterSlideSorter::disposing (const lang::EventObject
& rEventObject
)
434 throw (RuntimeException
, std::exception
)
436 if (rEventObject
.Source
== mxWindow
)
441 else if (rEventObject
.Source
== mxPreviewCache
)
443 mxPreviewCache
= NULL
;
446 else if (rEventObject
.Source
== mxCanvas
)
449 mbIsLayoutPending
= true;
450 mbIsPaintPending
= true;
452 mpPresenterController
->GetPaintManager()->Invalidate(mxWindow
);
456 //----- XWindowListener -------------------------------------------------------
458 void SAL_CALL
PresenterSlideSorter::windowResized (const awt::WindowEvent
& rEvent
)
459 throw (uno::RuntimeException
, std::exception
)
463 mbIsLayoutPending
= true;
464 mpPresenterController
->GetPaintManager()->Invalidate(mxWindow
);
467 void SAL_CALL
PresenterSlideSorter::windowMoved (const awt::WindowEvent
& rEvent
)
468 throw (uno::RuntimeException
, std::exception
)
474 void SAL_CALL
PresenterSlideSorter::windowShown (const lang::EventObject
& rEvent
)
475 throw (uno::RuntimeException
, std::exception
)
479 mbIsLayoutPending
= true;
480 mpPresenterController
->GetPaintManager()->Invalidate(mxWindow
);
483 void SAL_CALL
PresenterSlideSorter::windowHidden (const lang::EventObject
& rEvent
)
484 throw (uno::RuntimeException
, std::exception
)
490 //----- XPaintListener --------------------------------------------------------
492 void SAL_CALL
PresenterSlideSorter::windowPaint (const css::awt::PaintEvent
& rEvent
)
493 throw (RuntimeException
, std::exception
)
497 // Deactivated views must not be painted.
498 if ( ! mbIsPresenterViewActive
)
501 Paint(rEvent
.UpdateRect
);
503 Reference
<rendering::XSpriteCanvas
> xSpriteCanvas (mxCanvas
, UNO_QUERY
);
504 if (xSpriteCanvas
.is())
505 xSpriteCanvas
->updateScreen(sal_False
);
508 //----- XMouseListener --------------------------------------------------------
510 void SAL_CALL
PresenterSlideSorter::mousePressed (const css::awt::MouseEvent
& rEvent
)
511 throw(css::uno::RuntimeException
, std::exception
)
513 css::awt::MouseEvent rTemp
=rEvent
;
514 /// check whether RTL interface or not
515 if(AllSettings::GetLayoutRTL()){
516 awt::Rectangle aBox
= mxWindow
->getPosSize();
517 rTemp
.X
=aBox
.Width
-rEvent
.X
;
519 const geometry::RealPoint2D
aPosition(rTemp
.X
, rEvent
.Y
);
520 mnSlideIndexMousePressed
= mpLayout
->GetSlideIndexForPosition(aPosition
);
523 void SAL_CALL
PresenterSlideSorter::mouseReleased (const css::awt::MouseEvent
& rEvent
)
524 throw(css::uno::RuntimeException
, std::exception
)
526 css::awt::MouseEvent rTemp
=rEvent
;
527 /// check whether RTL interface or not
528 if(AllSettings::GetLayoutRTL()){
529 awt::Rectangle aBox
= mxWindow
->getPosSize();
530 rTemp
.X
=aBox
.Width
-rEvent
.X
;
532 const geometry::RealPoint2D
aPosition(rTemp
.X
, rEvent
.Y
);
533 const sal_Int32
nSlideIndex (mpLayout
->GetSlideIndexForPosition(aPosition
));
535 if (nSlideIndex
== mnSlideIndexMousePressed
&& mnSlideIndexMousePressed
>= 0)
537 switch (rEvent
.ClickCount
)
541 GotoSlide(nSlideIndex
);
545 OSL_ASSERT(mpPresenterController
.get()!=NULL
);
546 OSL_ASSERT(mpPresenterController
->GetWindowManager().get()!=NULL
);
547 mpPresenterController
->GetWindowManager()->SetSlideSorterState(false);
548 GotoSlide(nSlideIndex
);
554 void SAL_CALL
PresenterSlideSorter::mouseEntered (const css::awt::MouseEvent
& rEvent
)
555 throw(css::uno::RuntimeException
, std::exception
)
560 void SAL_CALL
PresenterSlideSorter::mouseExited (const css::awt::MouseEvent
& rEvent
)
561 throw(css::uno::RuntimeException
, std::exception
)
564 mnSlideIndexMousePressed
= -1;
565 if (mpMouseOverManager
.get() != NULL
)
566 mpMouseOverManager
->SetSlide(mnSlideIndexMousePressed
, awt::Rectangle(0,0,0,0));
569 //----- XMouseMotionListener --------------------------------------------------
571 void SAL_CALL
PresenterSlideSorter::mouseMoved (const css::awt::MouseEvent
& rEvent
)
572 throw (css::uno::RuntimeException
, std::exception
)
574 if (mpMouseOverManager
.get() != NULL
)
576 css::awt::MouseEvent rTemp
=rEvent
;
577 /// check whether RTL interface or not
578 if(AllSettings::GetLayoutRTL()){
579 awt::Rectangle aBox
= mxWindow
->getPosSize();
580 rTemp
.X
=aBox
.Width
-rEvent
.X
;
582 const geometry::RealPoint2D
aPosition(rTemp
.X
, rEvent
.Y
);
583 sal_Int32
nSlideIndex (mpLayout
->GetSlideIndexForPosition(aPosition
));
586 mnSlideIndexMousePressed
= -1;
590 mpMouseOverManager
->SetSlide(nSlideIndex
, awt::Rectangle(0,0,0,0));
594 mpMouseOverManager
->SetSlide(
596 mpLayout
->GetBoundingBox(nSlideIndex
));
601 void SAL_CALL
PresenterSlideSorter::mouseDragged (const css::awt::MouseEvent
& rEvent
)
602 throw (css::uno::RuntimeException
, std::exception
)
607 //----- XResourceId -----------------------------------------------------------
609 Reference
<XResourceId
> SAL_CALL
PresenterSlideSorter::getResourceId()
610 throw (RuntimeException
, std::exception
)
616 sal_Bool SAL_CALL
PresenterSlideSorter::isAnchorOnly()
617 throw (RuntimeException
, std::exception
)
622 //----- XPropertyChangeListener -----------------------------------------------
624 void SAL_CALL
PresenterSlideSorter::propertyChange (
625 const css::beans::PropertyChangeEvent
& rEvent
)
626 throw(css::uno::RuntimeException
, std::exception
)
631 //----- XSlidePreviewCacheListener --------------------------------------------
633 void SAL_CALL
PresenterSlideSorter::notifyPreviewCreation (
634 sal_Int32 nSlideIndex
)
635 throw(css::uno::RuntimeException
, std::exception
)
637 OSL_ASSERT(mpLayout
.get()!=NULL
);
639 awt::Rectangle
aBBox (mpLayout
->GetBoundingBox(nSlideIndex
));
640 mpPresenterController
->GetPaintManager()->Invalidate(mxWindow
, aBBox
, true);
643 //----- XDrawView -------------------------------------------------------------
645 void SAL_CALL
PresenterSlideSorter::setCurrentPage (const Reference
<drawing::XDrawPage
>& rxSlide
)
646 throw (RuntimeException
, std::exception
)
651 ::osl::MutexGuard
aGuard (::osl::Mutex::getGlobalMutex());
653 if (mxSlideShowController
.is())
655 const sal_Int32
nNewCurrentSlideIndex (mxSlideShowController
->getCurrentSlideIndex());
656 if (nNewCurrentSlideIndex
!= mnCurrentSlideIndex
)
658 mnCurrentSlideIndex
= nNewCurrentSlideIndex
;
660 // Request a repaint of the previous current slide to hide its
661 // current slide indicator.
662 mpPresenterController
->GetPaintManager()->Invalidate(
664 maCurrentSlideFrameBoundingBox
);
666 // Request a repaint of the new current slide to show its
667 // current slide indicator.
668 maCurrentSlideFrameBoundingBox
= mpCurrentSlideFrameRenderer
->GetBoundingBox(
669 mpLayout
->GetBoundingBox(mnCurrentSlideIndex
));
670 mpPresenterController
->GetPaintManager()->Invalidate(
672 maCurrentSlideFrameBoundingBox
);
677 Reference
<drawing::XDrawPage
> SAL_CALL
PresenterSlideSorter::getCurrentPage()
678 throw (RuntimeException
, std::exception
)
686 void PresenterSlideSorter::UpdateLayout()
688 if ( ! mxWindow
.is())
691 mbIsLayoutPending
= false;
692 mbIsPaintPending
= true;
694 const awt::Rectangle
aWindowBox (mxWindow
->getPosSize());
695 awt::Rectangle
aCenterBox (aWindowBox
);
696 sal_Int32
nLeftBorderWidth (aWindowBox
.X
);
699 PresenterPaneContainer::SharedPaneDescriptor
pPane (
700 mpPresenterController
->GetPaneContainer()->FindViewURL(
701 mxViewId
->getResourceURL()));
704 if (pPane
.get() == NULL
)
706 if ( ! pPane
->mxPane
.is())
709 Reference
<drawing::framework::XPaneBorderPainter
> xBorderPainter (
710 pPane
->mxPane
->GetPaneBorderPainter());
711 if ( ! xBorderPainter
.is())
713 aCenterBox
= xBorderPainter
->addBorder (
714 mxViewId
->getAnchor()->getResourceURL(),
715 awt::Rectangle(0, 0, aWindowBox
.Width
, aWindowBox
.Height
),
716 drawing::framework::BorderType_INNER_BORDER
);
720 // Place vertical separator.
721 mnSeparatorY
= aWindowBox
.Height
- mpCloseButton
->GetSize().Height
- gnVerticalButtonPadding
;
723 PlaceCloseButton(pPane
, aWindowBox
, nLeftBorderWidth
);
725 geometry::RealRectangle2D
aUpperBox(
728 aWindowBox
.Width
- 2*gnHorizontalBorder
,
729 mnSeparatorY
- gnVerticalGap
);
731 // Determine whether the scroll bar has to be displayed.
732 aUpperBox
= PlaceScrollBars(aUpperBox
);
734 mpLayout
->Update(aUpperBox
, GetSlideAspectRatio());
735 mpLayout
->SetupVisibleArea();
736 mpLayout
->UpdateScrollBars();
738 // Tell the preview cache about some of the values.
739 mxPreviewCache
->setPreviewSize(mpLayout
->maPreviewSize
);
740 mxPreviewCache
->setVisibleRange(
741 mpLayout
->GetFirstVisibleSlideIndex(),
742 mpLayout
->GetLastVisibleSlideIndex());
744 // Clear the frame polygon so that it is re-created on the next paint.
745 mxPreviewFrame
= NULL
;
748 geometry::RealRectangle2D
PresenterSlideSorter::PlaceScrollBars (
749 const geometry::RealRectangle2D
& rUpperBox
)
751 mpLayout
->Update(rUpperBox
, GetSlideAspectRatio());
752 bool bIsScrollBarNeeded (false);
753 Reference
<container::XIndexAccess
> xSlides (mxSlideShowController
, UNO_QUERY_THROW
);
755 bIsScrollBarNeeded
= mpLayout
->IsScrollBarNeeded(xSlides
->getCount());
756 if (mpVerticalScrollBar
.get() != NULL
)
758 if (bIsScrollBarNeeded
)
760 if(AllSettings::GetLayoutRTL())
762 mpVerticalScrollBar
->SetPosSize(geometry::RealRectangle2D(
765 rUpperBox
.X1
+ mpVerticalScrollBar
->GetSize(),
767 mpVerticalScrollBar
->SetVisible(true);
768 // Reduce area covered by the scroll bar from the available
770 return geometry::RealRectangle2D(
771 rUpperBox
.X1
+ gnHorizontalGap
+ mpVerticalScrollBar
->GetSize(),
778 // if its not RTL place vertical scroll bar at right border.
779 mpVerticalScrollBar
->SetPosSize(geometry::RealRectangle2D(
780 rUpperBox
.X2
- mpVerticalScrollBar
->GetSize(),
784 mpVerticalScrollBar
->SetVisible(true);
785 // Reduce area covered by the scroll bar from the available
787 return geometry::RealRectangle2D(
790 rUpperBox
.X2
- mpVerticalScrollBar
->GetSize() - gnHorizontalGap
,
795 mpVerticalScrollBar
->SetVisible(false);
800 void PresenterSlideSorter::PlaceCloseButton (
801 const PresenterPaneContainer::SharedPaneDescriptor
& rpPane
,
802 const awt::Rectangle
& rCenterBox
,
803 const sal_Int32 nLeftBorderWidth
)
805 // Place button. When the callout is near the center then the button is
806 // centered over the callout. Otherwise it is centered with respect to
808 sal_Int32
nCloseButtonCenter (rCenterBox
.Width
/2);
809 if (rpPane
.get() != NULL
&& rpPane
->mxPane
.is())
811 const sal_Int32
nCalloutCenter (rpPane
->mxPane
->GetCalloutAnchor().X
- nLeftBorderWidth
);
812 const sal_Int32
nDistanceFromWindowCenter (abs(nCalloutCenter
- rCenterBox
.Width
/2));
813 const sal_Int32
nButtonWidth (mpCloseButton
->GetSize().Width
);
814 const static sal_Int32
nMaxDistanceForCalloutCentering (nButtonWidth
* 2);
815 if (nDistanceFromWindowCenter
< nMaxDistanceForCalloutCentering
)
817 if (nCalloutCenter
< nButtonWidth
/2)
818 nCloseButtonCenter
= nButtonWidth
/2;
819 else if (nCalloutCenter
> rCenterBox
.Width
-nButtonWidth
/2)
820 nCloseButtonCenter
= rCenterBox
.Width
-nButtonWidth
/2;
822 nCloseButtonCenter
= nCalloutCenter
;
825 mpCloseButton
->SetCenter(geometry::RealPoint2D(
827 rCenterBox
.Height
- mpCloseButton
->GetSize().Height
/ 2));
830 void PresenterSlideSorter::ClearBackground (
831 const Reference
<rendering::XCanvas
>& rxCanvas
,
832 const awt::Rectangle
& rUpdateBox
)
834 OSL_ASSERT(rxCanvas
.is());
836 const awt::Rectangle
aWindowBox (mxWindow
->getPosSize());
837 mpPresenterController
->GetCanvasHelper()->Paint(
838 mpPresenterController
->GetViewBackground(mxViewId
->getResourceURL()),
841 awt::Rectangle(0,0,aWindowBox
.Width
,aWindowBox
.Height
),
845 double PresenterSlideSorter::GetSlideAspectRatio() const
847 double nSlideAspectRatio (28.0/21.0);
851 Reference
<container::XIndexAccess
> xSlides(mxSlideShowController
, UNO_QUERY_THROW
);
852 if (mxSlideShowController
.is() && xSlides
->getCount()>0)
854 Reference
<beans::XPropertySet
> xProperties(xSlides
->getByIndex(0),UNO_QUERY_THROW
);
855 sal_Int32
nWidth (28000);
856 sal_Int32
nHeight (21000);
857 if ((xProperties
->getPropertyValue("Width") >>= nWidth
)
858 && (xProperties
->getPropertyValue("Height") >>= nHeight
)
861 nSlideAspectRatio
= double(nWidth
) / double(nHeight
);
865 catch (RuntimeException
&)
870 return nSlideAspectRatio
;
873 Reference
<rendering::XBitmap
> PresenterSlideSorter::GetPreview (const sal_Int32 nSlideIndex
)
875 if (nSlideIndex
< 0 || nSlideIndex
>=mpLayout
->mnSlideCount
)
877 else if (mxPane
.is())
878 return mxPreviewCache
->getSlidePreview(nSlideIndex
, mxPane
->getCanvas());
883 void PresenterSlideSorter::PaintPreview (
884 const Reference
<rendering::XCanvas
>& rxCanvas
,
885 const css::awt::Rectangle
& rUpdateBox
,
886 const sal_Int32 nSlideIndex
)
888 OSL_ASSERT(rxCanvas
.is());
890 geometry::IntegerSize2D
aSize (mpLayout
->maPreviewSize
);
892 if (PresenterGeometryHelper::AreRectanglesDisjoint(
894 mpLayout
->GetBoundingBox(nSlideIndex
)))
899 Reference
<rendering::XBitmap
> xPreview (GetPreview(nSlideIndex
));
900 bool isRTL
= AllSettings::GetLayoutRTL();
902 const geometry::RealPoint2D
aTopLeft (
903 mpLayout
->GetWindowPosition(
904 mpLayout
->GetPoint(nSlideIndex
, isRTL
?1:-1, -1)));
906 PresenterBitmapContainer
aContainer (
907 "PresenterScreenSettings/ScrollBar/Bitmaps",
908 ::boost::shared_ptr
<PresenterBitmapContainer
>(),
911 Reference
<container::XIndexAccess
> xIndexAccess(mxSlideShowController
, UNO_QUERY
);
912 Reference
<drawing::XDrawPage
> xPage
= Reference
<drawing::XDrawPage
>(
913 xIndexAccess
->getByIndex(nSlideIndex
), UNO_QUERY
);
914 bool bTransition
= PresenterController::HasTransition(xPage
);
915 bool bCustomAnimation
= PresenterController::HasCustomAnimation(xPage
);
917 // Create clip rectangle as intersection of the current update area and
918 // the bounding box of all previews.
919 geometry::RealRectangle2D
aBoundingBox (mpLayout
->maBoundingBox
);
920 aBoundingBox
.Y2
+= 1;
921 const geometry::RealRectangle2D
aClipBox (
922 PresenterGeometryHelper::Intersection(
923 PresenterGeometryHelper::ConvertRectangle(rUpdateBox
),
925 Reference
<rendering::XPolyPolygon2D
> xClip (
926 PresenterGeometryHelper::CreatePolygon(aClipBox
, rxCanvas
->getDevice()));
928 const rendering::ViewState
aViewState (geometry::AffineMatrix2D(1,0,0, 0,1,0), xClip
);
930 rendering::RenderState
aRenderState (
931 geometry::AffineMatrix2D(
936 rendering::CompositeOperation::SOURCE
);
938 // Emphasize the current slide.
939 if (nSlideIndex
== mnCurrentSlideIndex
)
941 if (mpCurrentSlideFrameRenderer
.get() != NULL
)
943 const awt::Rectangle
aSlideBoundingBox(
944 sal::static_int_cast
<sal_Int32
>(0.5 + aTopLeft
.X
),
945 sal::static_int_cast
<sal_Int32
>(0.5 + aTopLeft
.Y
),
948 maCurrentSlideFrameBoundingBox
949 = mpCurrentSlideFrameRenderer
->GetBoundingBox(aSlideBoundingBox
);
950 mpCurrentSlideFrameRenderer
->PaintCurrentSlideFrame (
957 // Paint the preview.
960 aSize
= xPreview
->getSize();
961 if (aSize
.Width
> 0 && aSize
.Height
> 0)
963 rxCanvas
->drawBitmap(xPreview
, aViewState
, aRenderState
);
964 if( bCustomAnimation
)
966 const awt::Rectangle
aAnimationPreviewBox(aTopLeft
.X
+3, aTopLeft
.Y
+aSize
.Height
-40, 0, 0);
967 SharedBitmapDescriptor aAnimationDescriptor
= aContainer
.GetBitmap("Animation");
968 Reference
<rendering::XBitmap
> xAnimationIcon (aAnimationDescriptor
->GetNormalBitmap());
969 rendering::RenderState
aAnimationRenderState (
970 geometry::AffineMatrix2D(
971 1, 0, aAnimationPreviewBox
.X
,
972 0, 1, aAnimationPreviewBox
.Y
),
975 rendering::CompositeOperation::SOURCE
);
976 rxCanvas
->drawBitmap(xAnimationIcon
, aViewState
, aAnimationRenderState
);
980 const awt::Rectangle
aTransitionPreviewBox(aTopLeft
.X
+3, aTopLeft
.Y
+aSize
.Height
-20, 0, 0);
981 SharedBitmapDescriptor aTransitionDescriptor
= aContainer
.GetBitmap("Transition");
982 Reference
<rendering::XBitmap
> xTransitionIcon (aTransitionDescriptor
->GetNormalBitmap());
983 rendering::RenderState
aTransitionRenderState (
984 geometry::AffineMatrix2D(
985 1, 0, aTransitionPreviewBox
.X
,
986 0, 1, aTransitionPreviewBox
.Y
),
989 rendering::CompositeOperation::SOURCE
);
990 rxCanvas
->drawBitmap(xTransitionIcon
, aViewState
, aTransitionRenderState
);
995 // Create a polygon that is used to paint a frame around previews. Its
996 // coordinates are chosen in the local coordinate system of a preview.
997 if ( ! mxPreviewFrame
.is())
998 mxPreviewFrame
= PresenterGeometryHelper::CreatePolygon(
999 awt::Rectangle(-1, -1, aSize
.Width
+2, aSize
.Height
+2),
1000 rxCanvas
->getDevice());
1002 // Paint a border around the preview.
1003 if (mxPreviewFrame
.is())
1005 const geometry::RealRectangle2D
aBox (0, 0, aSize
.Width
, aSize
.Height
);
1006 const util::Color
aFrameColor (0x00000000);
1007 PresenterCanvasHelper::SetDeviceColor(aRenderState
, aFrameColor
);
1008 rxCanvas
->drawPolyPolygon(mxPreviewFrame
, aViewState
, aRenderState
);
1011 // Paint mouse over effect.
1012 mpMouseOverManager
->Paint(nSlideIndex
, mxCanvas
, xClip
);
1015 void PresenterSlideSorter::Paint (const awt::Rectangle
& rUpdateBox
)
1017 const bool bCanvasChanged ( ! mxCanvas
.is());
1018 if ( ! ProvideCanvas())
1021 if (mpLayout
->mnRowCount
<=0 || mpLayout
->mnColumnCount
<=0)
1023 OSL_ASSERT(mpLayout
->mnRowCount
>0 || mpLayout
->mnColumnCount
>0);
1027 mbIsPaintPending
= false;
1029 ClearBackground(mxCanvas
, rUpdateBox
);
1031 // Give the canvas to the controls.
1034 if (mpVerticalScrollBar
.is())
1035 mpVerticalScrollBar
->SetCanvas(mxCanvas
);
1036 if (mpCloseButton
.is())
1037 mpCloseButton
->SetCanvas(mxCanvas
, mxWindow
);
1040 // Now that the controls have a canvas we can do the layouting.
1041 if (mbIsLayoutPending
)
1044 // Paint the horizontal separator.
1045 rendering::RenderState
aRenderState (geometry::AffineMatrix2D(1,0,0, 0,1,0),
1046 NULL
, Sequence
<double>(4), rendering::CompositeOperation::SOURCE
);
1047 PresenterCanvasHelper::SetDeviceColor(aRenderState
, maSeparatorColor
);
1049 geometry::RealPoint2D(0, mnSeparatorY
),
1050 geometry::RealPoint2D(mxWindow
->getPosSize().Width
, mnSeparatorY
),
1051 rendering::ViewState(geometry::AffineMatrix2D(1,0,0, 0,1,0), NULL
),
1054 // Paint the slides.
1055 if ( ! PresenterGeometryHelper::AreRectanglesDisjoint(
1057 PresenterGeometryHelper::ConvertRectangle(mpLayout
->maBoundingBox
)))
1059 mpLayout
->ForAllVisibleSlides(
1060 ::boost::bind(&PresenterSlideSorter::PaintPreview
, this, mxCanvas
, rUpdateBox
, _1
));
1063 Reference
<rendering::XSpriteCanvas
> xSpriteCanvas (mxCanvas
, UNO_QUERY
);
1064 if (xSpriteCanvas
.is())
1065 xSpriteCanvas
->updateScreen(sal_False
);
1068 void PresenterSlideSorter::SetHorizontalOffset (const double nXOffset
)
1070 if (mpLayout
->SetHorizontalOffset(nXOffset
))
1072 mxPreviewCache
->setVisibleRange(
1073 mpLayout
->GetFirstVisibleSlideIndex(),
1074 mpLayout
->GetLastVisibleSlideIndex());
1076 mpPresenterController
->GetPaintManager()->Invalidate(mxWindow
);
1080 void PresenterSlideSorter::SetVerticalOffset (const double nYOffset
)
1082 if (mpLayout
->SetVerticalOffset(nYOffset
))
1084 mxPreviewCache
->setVisibleRange(
1085 mpLayout
->GetFirstVisibleSlideIndex(),
1086 mpLayout
->GetLastVisibleSlideIndex());
1088 mpPresenterController
->GetPaintManager()->Invalidate(mxWindow
);
1092 void PresenterSlideSorter::GotoSlide (const sal_Int32 nSlideIndex
)
1094 mxSlideShowController
->gotoSlideIndex(nSlideIndex
);
1097 bool PresenterSlideSorter::ProvideCanvas()
1099 if ( ! mxCanvas
.is())
1102 mxCanvas
= mxPane
->getCanvas();
1104 // Register as event listener so that we are informed when the
1105 // canvas is disposed (and we have to fetch another one).
1106 Reference
<lang::XComponent
> xComponent (mxCanvas
, UNO_QUERY
);
1107 if (xComponent
.is())
1108 xComponent
->addEventListener(static_cast<awt::XWindowListener
*>(this));
1110 mpCurrentSlideFrameRenderer
.reset(
1111 new CurrentSlideFrameRenderer(mxComponentContext
, mxCanvas
));
1113 return mxCanvas
.is();
1116 void PresenterSlideSorter::ThrowIfDisposed()
1117 throw (lang::DisposedException
)
1119 if (rBHelper
.bDisposed
|| rBHelper
.bInDispose
)
1121 throw lang::DisposedException (
1123 "PresenterSlideSorter has been already disposed"),
1124 const_cast<uno::XWeak
*>(static_cast<const uno::XWeak
*>(this)));
1128 //===== PresenterSlideSorter::Layout ==========================================
1130 PresenterSlideSorter::Layout::Layout (
1131 const ::rtl::Reference
<PresenterScrollBar
>& rpVerticalScrollBar
)
1134 mnHorizontalOffset(0),
1135 mnVerticalOffset(0),
1138 mnHorizontalBorder(0),
1139 mnVerticalBorder(0),
1143 mnSlideIndexAtMouse(-1),
1144 mnFirstVisibleColumn(-1),
1145 mnLastVisibleColumn(-1),
1146 mnFirstVisibleRow(-1),
1147 mnLastVisibleRow(-1),
1148 mpVerticalScrollBar(rpVerticalScrollBar
)
1152 void PresenterSlideSorter::Layout::Update (
1153 const geometry::RealRectangle2D
& rBoundingBox
,
1154 const double nSlideAspectRatio
)
1156 maBoundingBox
= rBoundingBox
;
1158 mnHorizontalBorder
= gnHorizontalBorder
;
1159 mnVerticalBorder
= gnVerticalBorder
;
1161 const double nWidth (rBoundingBox
.X2
- rBoundingBox
.X1
- 2*mnHorizontalBorder
);
1162 const double nHeight (rBoundingBox
.Y2
- rBoundingBox
.Y1
- 2*mnVerticalBorder
);
1163 if (nWidth
<=0 || nHeight
<=0)
1166 double nPreviewWidth
;
1168 // Determine column count, preview width, and horizontal gap (borders
1169 // are half the gap). Try to use the preferred values. Try more to
1170 // stay in the valid intervalls. This last constraint may be not
1171 // fulfilled in some cases.
1172 const double nElementWidth
= nWidth
/ gnPreferredColumnCount
;
1173 if (nElementWidth
< gnMinimalPreviewWidth
+ gnMinimalHorizontalPreviewGap
)
1175 // The preferred column count is too large.
1176 // Can we use the preferred preview width?
1177 if (nWidth
- gnMinimalHorizontalPreviewGap
>= gnPreferredPreviewWidth
)
1180 nPreviewWidth
= gnPreferredPreviewWidth
;
1181 mnColumnCount
= floor((nWidth
+gnPreferredHorizontalPreviewGap
)
1182 / (nPreviewWidth
+gnPreferredHorizontalPreviewGap
));
1183 mnHorizontalGap
= round((nWidth
- mnColumnCount
*nPreviewWidth
) / mnColumnCount
);
1187 // No. Set the column count to 1 and adapt preview width and
1190 mnHorizontalGap
= floor(gnMinimalHorizontalPreviewGap
);
1191 if (nWidth
- gnMinimalHorizontalPreviewGap
>= gnPreferredPreviewWidth
)
1192 nPreviewWidth
= nWidth
- gnMinimalHorizontalPreviewGap
;
1194 nPreviewWidth
= ::std::max(gnMinimalPreviewWidth
, nWidth
-mnHorizontalGap
);
1197 else if (nElementWidth
> gnMaximalPreviewWidth
+ gnMaximalHorizontalPreviewGap
)
1199 // The preferred column count is too small.
1200 nPreviewWidth
= gnPreferredPreviewWidth
;
1201 mnColumnCount
= floor((nWidth
+gnPreferredHorizontalPreviewGap
)
1202 / (nPreviewWidth
+gnPreferredHorizontalPreviewGap
));
1203 mnHorizontalGap
= round((nWidth
- mnColumnCount
*nPreviewWidth
) / mnColumnCount
);
1207 // The preferred column count is possible. Determine gap and
1209 mnColumnCount
= gnPreferredColumnCount
;
1210 if (nElementWidth
- gnPreferredPreviewWidth
< gnMinimalHorizontalPreviewGap
)
1212 // Use the minimal gap and adapt the preview width.
1213 mnHorizontalGap
= floor(gnMinimalHorizontalPreviewGap
);
1214 nPreviewWidth
= (nWidth
- mnColumnCount
*mnHorizontalGap
) / mnColumnCount
;
1216 else if (nElementWidth
- gnPreferredPreviewWidth
<= gnMaximalHorizontalPreviewGap
)
1218 // Use the maximal gap and adapt the preview width.
1219 mnHorizontalGap
= round(gnMaximalHorizontalPreviewGap
);
1220 nPreviewWidth
= (nWidth
- mnColumnCount
*mnHorizontalGap
) / mnColumnCount
;
1224 // Use the preferred preview width and adapt the gap.
1225 nPreviewWidth
= gnPreferredPreviewWidth
;
1226 mnHorizontalGap
= round((nWidth
- mnColumnCount
*nPreviewWidth
) / mnColumnCount
);
1230 // Now determine the row count, preview height, and vertical gap.
1231 const double nPreviewHeight
= nPreviewWidth
/ nSlideAspectRatio
;
1232 mnRowCount
= ::std::max(
1234 sal_Int32(ceil((nHeight
+gnPreferredVerticalPreviewGap
)
1235 / (nPreviewHeight
+ gnPreferredVerticalPreviewGap
))));
1236 mnVerticalGap
= round(gnPreferredVerticalPreviewGap
);
1238 maPreviewSize
= geometry::IntegerSize2D(floor(nPreviewWidth
), floor(nPreviewHeight
));
1240 // Reset the offset.
1241 mnVerticalOffset
= 0;
1242 mnHorizontalOffset
= round(-(nWidth
1243 - mnColumnCount
*maPreviewSize
.Width
1244 - (mnColumnCount
-1)*mnHorizontalGap
)
1248 void PresenterSlideSorter::Layout::SetupVisibleArea()
1250 geometry::RealPoint2D
aPoint (GetLocalPosition(
1251 geometry::RealPoint2D(maBoundingBox
.X1
, maBoundingBox
.Y1
)));
1252 mnFirstVisibleColumn
= 0;
1253 mnFirstVisibleRow
= ::std::max(sal_Int32(0), GetRow(aPoint
));
1255 aPoint
= GetLocalPosition(geometry::RealPoint2D( maBoundingBox
.X2
, maBoundingBox
.Y2
));
1256 mnLastVisibleColumn
= mnColumnCount
- 1;
1257 mnLastVisibleRow
= GetRow(aPoint
, true);
1260 bool PresenterSlideSorter::Layout::IsScrollBarNeeded (const sal_Int32 nSlideCount
)
1262 geometry::RealPoint2D aBottomRight
;
1263 aBottomRight
= GetPoint(
1264 mnColumnCount
* (GetRow(nSlideCount
)+1) - 1, +1, +1);
1265 return aBottomRight
.X
> maBoundingBox
.X2
-maBoundingBox
.X1
1266 || aBottomRight
.Y
> maBoundingBox
.Y2
-maBoundingBox
.Y1
;
1269 geometry::RealPoint2D
PresenterSlideSorter::Layout::GetLocalPosition(
1270 const geometry::RealPoint2D
& rWindowPoint
) const
1272 if(AllSettings::GetLayoutRTL())
1274 return css::geometry::RealPoint2D(
1275 -rWindowPoint
.X
+ maBoundingBox
.X2
+ mnHorizontalOffset
,
1276 rWindowPoint
.Y
- maBoundingBox
.Y1
+ mnVerticalOffset
);
1280 return css::geometry::RealPoint2D(
1281 rWindowPoint
.X
- maBoundingBox
.X1
+ mnHorizontalOffset
,
1282 rWindowPoint
.Y
- maBoundingBox
.Y1
+ mnVerticalOffset
);
1286 geometry::RealPoint2D
PresenterSlideSorter::Layout::GetWindowPosition(
1287 const geometry::RealPoint2D
& rLocalPoint
) const
1289 if(AllSettings::GetLayoutRTL())
1291 return css::geometry::RealPoint2D(
1292 -rLocalPoint
.X
+ mnHorizontalOffset
+ maBoundingBox
.X2
,
1293 rLocalPoint
.Y
- mnVerticalOffset
+ maBoundingBox
.Y1
);
1297 return css::geometry::RealPoint2D(
1298 rLocalPoint
.X
- mnHorizontalOffset
+ maBoundingBox
.X1
,
1299 rLocalPoint
.Y
- mnVerticalOffset
+ maBoundingBox
.Y1
);
1303 sal_Int32
PresenterSlideSorter::Layout::GetColumn (
1304 const css::geometry::RealPoint2D
& rLocalPoint
,
1305 const bool bReturnInvalidValue
) const
1307 const sal_Int32
nColumn(floor(
1308 (rLocalPoint
.X
+ mnHorizontalGap
/2.0) / (maPreviewSize
.Width
+mnHorizontalGap
)));
1309 if (bReturnInvalidValue
1310 || (nColumn
>=mnFirstVisibleColumn
&& nColumn
<=mnLastVisibleColumn
))
1318 sal_Int32
PresenterSlideSorter::Layout::GetRow (
1319 const css::geometry::RealPoint2D
& rLocalPoint
,
1320 const bool bReturnInvalidValue
) const
1322 const sal_Int32
nRow (floor(
1323 (rLocalPoint
.Y
+ mnVerticalGap
/2.0) / (maPreviewSize
.Height
+mnVerticalGap
)));
1324 if (bReturnInvalidValue
1325 || (nRow
>=mnFirstVisibleRow
&& nRow
<=mnLastVisibleRow
))
1333 sal_Int32
PresenterSlideSorter::Layout::GetSlideIndexForPosition (
1334 const css::geometry::RealPoint2D
& rWindowPoint
) const
1336 if ( ! PresenterGeometryHelper::IsInside(maBoundingBox
, rWindowPoint
))
1339 const css::geometry::RealPoint2D
aLocalPosition (GetLocalPosition(rWindowPoint
));
1340 const sal_Int32
nColumn (GetColumn(aLocalPosition
));
1341 const sal_Int32
nRow (GetRow(aLocalPosition
));
1343 if (nColumn
< 0 || nRow
< 0)
1347 sal_Int32
nIndex (GetIndex(nRow
, nColumn
));
1348 if (nIndex
>= mnSlideCount
)
1355 geometry::RealPoint2D
PresenterSlideSorter::Layout::GetPoint (
1356 const sal_Int32 nSlideIndex
,
1357 const sal_Int32 nRelativeHorizontalPosition
,
1358 const sal_Int32 nRelativeVerticalPosition
) const
1360 sal_Int32
nColumn (GetColumn(nSlideIndex
));
1361 sal_Int32
nRow (GetRow(nSlideIndex
));
1363 geometry::RealPoint2D
aPosition (
1364 mnHorizontalBorder
+ nColumn
*(maPreviewSize
.Width
+mnHorizontalGap
),
1365 mnVerticalBorder
+ nRow
*(maPreviewSize
.Height
+mnVerticalGap
));
1367 if (nRelativeHorizontalPosition
>= 0)
1369 if (nRelativeHorizontalPosition
> 0)
1370 aPosition
.X
+= maPreviewSize
.Width
;
1372 aPosition
.X
+= maPreviewSize
.Width
/ 2.0;
1374 if (nRelativeVerticalPosition
>= 0)
1376 if (nRelativeVerticalPosition
> 0)
1377 aPosition
.Y
+= maPreviewSize
.Height
;
1379 aPosition
.Y
+= maPreviewSize
.Height
/ 2.0;
1385 awt::Rectangle
PresenterSlideSorter::Layout::GetBoundingBox (const sal_Int32 nSlideIndex
) const
1387 bool isRTL
= AllSettings::GetLayoutRTL();
1388 const geometry::RealPoint2D
aWindowPosition(GetWindowPosition(GetPoint(nSlideIndex
, isRTL
?1:-1, -1)));
1389 return PresenterGeometryHelper::ConvertRectangle(
1390 geometry::RealRectangle2D(
1393 aWindowPosition
.X
+ maPreviewSize
.Width
,
1394 aWindowPosition
.Y
+ maPreviewSize
.Height
));
1397 void PresenterSlideSorter::Layout::ForAllVisibleSlides (const ::boost::function
<void(sal_Int32
)>& rAction
)
1399 for (sal_Int32 nRow
=mnFirstVisibleRow
; nRow
<=mnLastVisibleRow
; ++nRow
)
1401 for (sal_Int32 nColumn
=mnFirstVisibleColumn
; nColumn
<=mnLastVisibleColumn
; ++nColumn
)
1403 const sal_Int32
nSlideIndex (GetIndex(nRow
, nColumn
));
1404 if (nSlideIndex
>= mnSlideCount
)
1406 rAction(nSlideIndex
);
1411 sal_Int32
PresenterSlideSorter::Layout::GetFirstVisibleSlideIndex() const
1413 return GetIndex(mnFirstVisibleRow
, mnFirstVisibleColumn
);
1416 sal_Int32
PresenterSlideSorter::Layout::GetLastVisibleSlideIndex() const
1419 GetIndex(mnLastVisibleRow
, mnLastVisibleColumn
),
1423 bool PresenterSlideSorter::Layout::SetHorizontalOffset (const double nOffset
)
1425 if (mnHorizontalOffset
!= nOffset
)
1427 mnHorizontalOffset
= round(nOffset
);
1436 bool PresenterSlideSorter::Layout::SetVerticalOffset (const double nOffset
)
1438 if (mnVerticalOffset
!= nOffset
)
1440 mnVerticalOffset
= round(nOffset
);
1449 void PresenterSlideSorter::Layout::UpdateScrollBars()
1451 sal_Int32
nTotalRowCount (0);
1452 nTotalRowCount
= sal_Int32(ceil(double(mnSlideCount
) / double(mnColumnCount
)));
1454 if (mpVerticalScrollBar
.get() != NULL
)
1456 mpVerticalScrollBar
->SetTotalSize(
1457 nTotalRowCount
* maPreviewSize
.Height
1458 + (nTotalRowCount
-1) * mnVerticalGap
1460 mpVerticalScrollBar
->SetThumbPosition(mnVerticalOffset
, false);
1461 mpVerticalScrollBar
->SetThumbSize(maBoundingBox
.Y2
- maBoundingBox
.Y1
+ 1);
1462 mpVerticalScrollBar
->SetLineHeight(maPreviewSize
.Height
);
1465 // No place yet for the vertical scroll bar.
1468 sal_Int32
PresenterSlideSorter::Layout::GetIndex (
1469 const sal_Int32 nRow
,
1470 const sal_Int32 nColumn
) const
1472 return nRow
* mnColumnCount
+ nColumn
;
1475 sal_Int32
PresenterSlideSorter::Layout::GetRow (const sal_Int32 nSlideIndex
) const
1477 return nSlideIndex
/ mnColumnCount
;
1480 sal_Int32
PresenterSlideSorter::Layout::GetColumn (const sal_Int32 nSlideIndex
) const
1482 return nSlideIndex
% mnColumnCount
;
1485 //===== PresenterSlideSorter::MouseOverManager ================================
1487 PresenterSlideSorter::MouseOverManager::MouseOverManager (
1488 const Reference
<container::XIndexAccess
>& rxSlides
,
1489 const ::boost::shared_ptr
<PresenterTheme
>& rpTheme
,
1490 const Reference
<awt::XWindow
>& rxInvalidateTarget
,
1491 const ::boost::shared_ptr
<PresenterPaintManager
>& rpPaintManager
)
1494 mpLeftLabelBitmap(),
1495 mpCenterLabelBitmap(),
1496 mpRightLabelBitmap(),
1499 maSlideBoundingBox(),
1500 mxInvalidateTarget(rxInvalidateTarget
),
1501 mpPaintManager(rpPaintManager
)
1503 if (rpTheme
.get()!=NULL
)
1505 ::boost::shared_ptr
<PresenterBitmapContainer
> pBitmaps (rpTheme
->GetBitmapContainer());
1506 if (pBitmaps
.get() != NULL
)
1508 mpLeftLabelBitmap
= pBitmaps
->GetBitmap("LabelLeft");
1509 mpCenterLabelBitmap
= pBitmaps
->GetBitmap("LabelCenter");
1510 mpRightLabelBitmap
= pBitmaps
->GetBitmap("LabelRight");
1513 mpFont
= rpTheme
->GetFont("SlideSorterLabelFont");
1517 PresenterSlideSorter::MouseOverManager::~MouseOverManager()
1521 void PresenterSlideSorter::MouseOverManager::Paint (
1522 const sal_Int32 nSlideIndex
,
1523 const Reference
<rendering::XCanvas
>& rxCanvas
,
1524 const Reference
<rendering::XPolyPolygon2D
>& rxClip
)
1526 if (nSlideIndex
!= mnSlideIndex
)
1529 if (mxCanvas
!= rxCanvas
)
1530 SetCanvas(rxCanvas
);
1531 if (rxCanvas
!= NULL
)
1533 if ( ! mxBitmap
.is())
1534 mxBitmap
= CreateBitmap(msText
, maSlideBoundingBox
.Width
);
1537 geometry::IntegerSize2D
aSize (mxBitmap
->getSize());
1538 const double nXOffset (maSlideBoundingBox
.X
1539 + (maSlideBoundingBox
.Width
- aSize
.Width
) / 2.0);
1540 const double nYOffset (maSlideBoundingBox
.Y
1541 + (maSlideBoundingBox
.Height
- aSize
.Height
) / 2.0);
1542 rxCanvas
->drawBitmap(
1544 rendering::ViewState(
1545 geometry::AffineMatrix2D(1,0,0, 0,1,0),
1547 rendering::RenderState(
1548 geometry::AffineMatrix2D(1,0,nXOffset
, 0,1,nYOffset
),
1550 Sequence
<double>(4),
1551 rendering::CompositeOperation::SOURCE
));
1556 void PresenterSlideSorter::MouseOverManager::SetCanvas (
1557 const Reference
<rendering::XCanvas
>& rxCanvas
)
1559 mxCanvas
= rxCanvas
;
1560 if (mpFont
.get() != NULL
)
1561 mpFont
->PrepareFont(Reference
<rendering::XCanvas
>(mxCanvas
, UNO_QUERY
));
1564 void PresenterSlideSorter::MouseOverManager::SetSlide (
1565 const sal_Int32 nSlideIndex
,
1566 const awt::Rectangle
& rBox
)
1568 if (mnSlideIndex
== nSlideIndex
)
1574 maSlideBoundingBox
= rBox
;
1575 mnSlideIndex
= nSlideIndex
;
1577 if (nSlideIndex
>= 0)
1579 if (mxSlides
.get() != NULL
)
1583 Reference
<beans::XPropertySet
> xSlideProperties(mxSlides
->getByIndex(nSlideIndex
), UNO_QUERY
);
1584 if (xSlideProperties
.is())
1585 xSlideProperties
->getPropertyValue("LinkDisplayName") >>= msText
;
1587 if (msText
.isEmpty())
1588 msText
= "Slide " + OUString::number(nSlideIndex
+ 1);
1600 Reference
<rendering::XBitmap
> PresenterSlideSorter::MouseOverManager::CreateBitmap (
1601 const OUString
& rsText
,
1602 const sal_Int32 nMaximalWidth
) const
1604 if ( ! mxCanvas
.is())
1607 if (mpFont
.get()==NULL
|| !mpFont
->mxFont
.is())
1610 // Long text has to be shortened.
1611 const OUString
sText (GetFittingText(rsText
, nMaximalWidth
1612 - 2*gnHorizontalLabelBorder
1613 - 2*gnHorizontalLabelPadding
));
1615 // Determine the size of the label. Its height is defined by the
1616 // bitmaps that are used to paints its background. The width is defined
1618 geometry::IntegerSize2D
aLabelSize (CalculateLabelSize(sText
));
1620 // Create a new bitmap that will contain the complete label.
1621 Reference
<rendering::XBitmap
> xBitmap (
1622 mxCanvas
->getDevice()->createCompatibleAlphaBitmap(aLabelSize
));
1624 if ( ! xBitmap
.is())
1627 Reference
<rendering::XBitmapCanvas
> xBitmapCanvas (xBitmap
, UNO_QUERY
);
1628 if ( ! xBitmapCanvas
.is())
1631 // Paint the background.
1632 PaintButtonBackground(xBitmapCanvas
, aLabelSize
);
1635 if (!sText
.isEmpty())
1638 const rendering::StringContext
aContext (sText
, 0, sText
.getLength());
1639 const Reference
<rendering::XTextLayout
> xLayout (mpFont
->mxFont
->createTextLayout(
1640 aContext
, rendering::TextDirection::WEAK_LEFT_TO_RIGHT
,0));
1641 const geometry::RealRectangle2D
aTextBBox (xLayout
->queryTextBounds());
1643 const double nXOffset
= (aLabelSize
.Width
- aTextBBox
.X2
+ aTextBBox
.X1
) / 2;
1644 const double nYOffset
= aLabelSize
.Height
1645 - (aLabelSize
.Height
- aTextBBox
.Y2
+ aTextBBox
.Y1
)/2 - aTextBBox
.Y2
;
1647 const rendering::ViewState
aViewState(
1648 geometry::AffineMatrix2D(1,0,0, 0,1,0),
1651 rendering::RenderState
aRenderState (
1652 geometry::AffineMatrix2D(1,0,nXOffset
, 0,1,nYOffset
),
1654 Sequence
<double>(4),
1655 rendering::CompositeOperation::SOURCE
);
1656 PresenterCanvasHelper::SetDeviceColor(aRenderState
, mpFont
->mnColor
);
1658 xBitmapCanvas
->drawTextLayout (
1667 OUString
PresenterSlideSorter::MouseOverManager::GetFittingText (
1668 const OUString
& rsText
,
1669 const double nMaximalWidth
) const
1671 const double nTextWidth (
1672 PresenterCanvasHelper::GetTextSize(mpFont
->mxFont
, rsText
).Width
);
1673 if (nTextWidth
> nMaximalWidth
)
1675 // Text is too wide. Shorten it by removing characters from the end
1676 // and replacing them by ellipses.
1678 // Guess a start value of the final string length.
1679 double nBestWidth (0);
1680 OUString sBestCandidate
;
1681 sal_Int32
nLength (round(rsText
.getLength() * nMaximalWidth
/ nTextWidth
));
1682 const OUString
sEllipses ("...");
1685 const OUString
sCandidate (rsText
.copy(0,nLength
) + sEllipses
);
1686 const double nWidth (
1687 PresenterCanvasHelper::GetTextSize(mpFont
->mxFont
, sCandidate
).Width
);
1688 if (nWidth
> nMaximalWidth
)
1690 // Candidate still too wide, shorten it.
1695 else if (nWidth
< nMaximalWidth
)
1697 // Candidate short enough.
1698 if (nWidth
> nBestWidth
)
1700 // Best length so far.
1701 sBestCandidate
= sCandidate
;
1702 nBestWidth
= nWidth
;
1704 if (nLength
>= rsText
.getLength())
1712 // Candidate is exactly as long as it may be. Use it
1713 // without looking any further.
1714 sBestCandidate
= sCandidate
;
1718 return sBestCandidate
;
1724 geometry::IntegerSize2D
PresenterSlideSorter::MouseOverManager::CalculateLabelSize (
1725 const OUString
& rsText
) const
1727 // Height is specified by the label bitmaps.
1728 sal_Int32
nHeight (32);
1729 if (mpCenterLabelBitmap
.get() != NULL
)
1731 Reference
<rendering::XBitmap
> xBitmap (mpCenterLabelBitmap
->GetNormalBitmap());
1733 nHeight
= xBitmap
->getSize().Height
;
1736 // Width is specified by text width and maximal width.
1737 const geometry::RealSize2D
aTextSize (
1738 PresenterCanvasHelper::GetTextSize(mpFont
->mxFont
, rsText
));
1740 const sal_Int32
nWidth (round(aTextSize
.Width
+ 2*gnHorizontalLabelPadding
));
1742 return geometry::IntegerSize2D(nWidth
, nHeight
);
1745 void PresenterSlideSorter::MouseOverManager::PaintButtonBackground (
1746 const Reference
<rendering::XCanvas
>& rxCanvas
,
1747 const geometry::IntegerSize2D
& rSize
) const
1749 // Get the bitmaps for painting the label background.
1750 Reference
<rendering::XBitmap
> xLeftLabelBitmap
;
1751 if (mpLeftLabelBitmap
.get() != NULL
)
1752 xLeftLabelBitmap
= mpLeftLabelBitmap
->GetNormalBitmap();
1754 Reference
<rendering::XBitmap
> xCenterLabelBitmap
;
1755 if (mpCenterLabelBitmap
.get() != NULL
)
1756 xCenterLabelBitmap
= mpCenterLabelBitmap
->GetNormalBitmap();
1758 Reference
<rendering::XBitmap
> xRightLabelBitmap
;
1759 if (mpRightLabelBitmap
.get() != NULL
)
1760 xRightLabelBitmap
= mpRightLabelBitmap
->GetNormalBitmap();
1762 PresenterUIPainter::PaintHorizontalBitmapComposite (
1763 Reference
<rendering::XCanvas
>(rxCanvas
, UNO_QUERY
),
1764 awt::Rectangle(0,0, rSize
.Width
,rSize
.Height
),
1765 awt::Rectangle(0,0, rSize
.Width
,rSize
.Height
),
1771 void PresenterSlideSorter::MouseOverManager::Invalidate()
1773 if (mpPaintManager
.get() != NULL
)
1774 mpPaintManager
->Invalidate(mxInvalidateTarget
, maSlideBoundingBox
, true);
1777 //===== PresenterSlideSorter::CurrentSlideFrameRenderer =======================
1779 PresenterSlideSorter::CurrentSlideFrameRenderer::CurrentSlideFrameRenderer (
1780 const css::uno::Reference
<css::uno::XComponentContext
>& rxContext
,
1781 const css::uno::Reference
<css::rendering::XCanvas
>& rxCanvas
)
1792 mnRightFrameSize(0),
1793 mnBottomFrameSize(0)
1795 PresenterConfigurationAccess
aConfiguration (
1797 OUString("/org.openoffice.Office.PresenterScreen/"),
1798 PresenterConfigurationAccess::READ_ONLY
);
1799 Reference
<container::XHierarchicalNameAccess
> xBitmaps (
1800 aConfiguration
.GetConfigurationNode(
1801 "PresenterScreenSettings/SlideSorter/CurrentSlideBorderBitmaps"),
1803 if ( ! xBitmaps
.is())
1806 PresenterBitmapContainer
aContainer (
1807 "PresenterScreenSettings/SlideSorter/CurrentSlideBorderBitmaps",
1808 ::boost::shared_ptr
<PresenterBitmapContainer
>(),
1812 mpTopLeft
= aContainer
.GetBitmap("TopLeft");
1813 mpTop
= aContainer
.GetBitmap("Top");
1814 mpTopRight
= aContainer
.GetBitmap("TopRight");
1815 mpLeft
= aContainer
.GetBitmap("Left");
1816 mpRight
= aContainer
.GetBitmap("Right");
1817 mpBottomLeft
= aContainer
.GetBitmap("BottomLeft");
1818 mpBottom
= aContainer
.GetBitmap("Bottom");
1819 mpBottomRight
= aContainer
.GetBitmap("BottomRight");
1821 // Determine size of frame.
1822 if (mpTop
.get() != NULL
)
1823 mnTopFrameSize
= mpTop
->mnHeight
;
1824 if (mpLeft
.get() != NULL
)
1825 mnLeftFrameSize
= mpLeft
->mnWidth
;
1826 if (mpRight
.get() != NULL
)
1827 mnRightFrameSize
= mpRight
->mnWidth
;
1828 if (mpBottom
.get() != NULL
)
1829 mnBottomFrameSize
= mpBottom
->mnHeight
;
1831 if (mpTopLeft
.get() != NULL
)
1833 mnTopFrameSize
= ::std::max(mnTopFrameSize
, mpTopLeft
->mnHeight
);
1834 mnLeftFrameSize
= ::std::max(mnLeftFrameSize
, mpTopLeft
->mnWidth
);
1836 if (mpTopRight
.get() != NULL
)
1838 mnTopFrameSize
= ::std::max(mnTopFrameSize
, mpTopRight
->mnHeight
);
1839 mnRightFrameSize
= ::std::max(mnRightFrameSize
, mpTopRight
->mnWidth
);
1841 if (mpBottomLeft
.get() != NULL
)
1843 mnLeftFrameSize
= ::std::max(mnLeftFrameSize
, mpBottomLeft
->mnWidth
);
1844 mnBottomFrameSize
= ::std::max(mnBottomFrameSize
, mpBottomLeft
->mnHeight
);
1846 if (mpBottomRight
.get() != NULL
)
1848 mnRightFrameSize
= ::std::max(mnRightFrameSize
, mpBottomRight
->mnWidth
);
1849 mnBottomFrameSize
= ::std::max(mnBottomFrameSize
, mpBottomRight
->mnHeight
);
1853 PresenterSlideSorter::CurrentSlideFrameRenderer::~CurrentSlideFrameRenderer()
1857 void PresenterSlideSorter::CurrentSlideFrameRenderer::PaintCurrentSlideFrame (
1858 const awt::Rectangle
& rSlideBoundingBox
,
1859 const Reference
<rendering::XCanvas
>& rxCanvas
,
1860 const geometry::RealRectangle2D
& rClipBox
)
1862 if ( ! rxCanvas
.is())
1865 const Reference
<rendering::XPolyPolygon2D
> xClip (
1866 PresenterGeometryHelper::CreatePolygon(rClipBox
, rxCanvas
->getDevice()));
1868 if (mpTop
.get() != NULL
)
1871 mpTop
->GetNormalBitmap(),
1874 rSlideBoundingBox
.X
,
1875 rSlideBoundingBox
.Y
- mpTop
->mnHeight
,
1876 rSlideBoundingBox
.Width
,
1879 if (mpLeft
.get() != NULL
)
1882 mpLeft
->GetNormalBitmap(),
1885 rSlideBoundingBox
.X
- mpLeft
->mnWidth
,
1886 rSlideBoundingBox
.Y
,
1888 rSlideBoundingBox
.Height
);
1890 if (mpRight
.get() != NULL
)
1893 mpRight
->GetNormalBitmap(),
1896 rSlideBoundingBox
.X
+ rSlideBoundingBox
.Width
,
1897 rSlideBoundingBox
.Y
,
1899 rSlideBoundingBox
.Height
);
1901 if (mpBottom
.get() != NULL
)
1904 mpBottom
->GetNormalBitmap(),
1907 rSlideBoundingBox
.X
,
1908 rSlideBoundingBox
.Y
+ rSlideBoundingBox
.Height
,
1909 rSlideBoundingBox
.Width
,
1910 mpBottom
->mnHeight
);
1912 if (mpTopLeft
.get() != NULL
)
1915 mpTopLeft
->GetNormalBitmap(),
1918 rSlideBoundingBox
.X
- mpTopLeft
->mnWidth
,
1919 rSlideBoundingBox
.Y
- mpTopLeft
->mnHeight
);
1921 if (mpTopRight
.get() != NULL
)
1924 mpTopRight
->GetNormalBitmap(),
1927 rSlideBoundingBox
.X
+ rSlideBoundingBox
.Width
,
1928 rSlideBoundingBox
.Y
- mpTopLeft
->mnHeight
);
1930 if (mpBottomLeft
.get() != NULL
)
1933 mpBottomLeft
->GetNormalBitmap(),
1936 rSlideBoundingBox
.X
- mpBottomLeft
->mnWidth
,
1937 rSlideBoundingBox
.Y
+ rSlideBoundingBox
.Height
);
1939 if (mpBottomRight
.get() != NULL
)
1942 mpBottomRight
->GetNormalBitmap(),
1945 rSlideBoundingBox
.X
+ rSlideBoundingBox
.Width
,
1946 rSlideBoundingBox
.Y
+ rSlideBoundingBox
.Height
);
1950 awt::Rectangle
PresenterSlideSorter::CurrentSlideFrameRenderer::GetBoundingBox (
1951 const awt::Rectangle
& rSlideBoundingBox
)
1953 return awt::Rectangle(
1954 rSlideBoundingBox
.X
- mnLeftFrameSize
,
1955 rSlideBoundingBox
.Y
- mnTopFrameSize
,
1956 rSlideBoundingBox
.Width
+ mnLeftFrameSize
+ mnRightFrameSize
,
1957 rSlideBoundingBox
.Height
+ mnTopFrameSize
+ mnBottomFrameSize
);
1960 void PresenterSlideSorter::CurrentSlideFrameRenderer::PaintBitmapOnce(
1961 const css::uno::Reference
<css::rendering::XBitmap
>& rxBitmap
,
1962 const css::uno::Reference
<css::rendering::XCanvas
>& rxCanvas
,
1963 const Reference
<rendering::XPolyPolygon2D
>& rxClip
,
1967 OSL_ASSERT(rxCanvas
.is());
1968 if ( ! rxBitmap
.is())
1971 const rendering::ViewState
aViewState(
1972 geometry::AffineMatrix2D(1,0,0, 0,1,0),
1975 const rendering::RenderState
aRenderState (
1976 geometry::AffineMatrix2D(
1980 Sequence
<double>(4),
1981 rendering::CompositeOperation::SOURCE
);
1983 rxCanvas
->drawBitmap(
1989 void PresenterSlideSorter::CurrentSlideFrameRenderer::PaintBitmapTiled(
1990 const css::uno::Reference
<css::rendering::XBitmap
>& rxBitmap
,
1991 const css::uno::Reference
<css::rendering::XCanvas
>& rxCanvas
,
1992 const geometry::RealRectangle2D
& rClipBox
,
1995 const double nWidth
,
1996 const double nHeight
)
1998 OSL_ASSERT(rxCanvas
.is());
1999 if ( ! rxBitmap
.is())
2002 geometry::IntegerSize2D
aSize (rxBitmap
->getSize());
2004 const rendering::ViewState
aViewState(
2005 geometry::AffineMatrix2D(1,0,0, 0,1,0),
2006 PresenterGeometryHelper::CreatePolygon(
2007 PresenterGeometryHelper::Intersection(
2009 geometry::RealRectangle2D(nX0
,nY0
,nX0
+nWidth
,nY0
+nHeight
)),
2010 rxCanvas
->getDevice()));
2012 rendering::RenderState
aRenderState (
2013 geometry::AffineMatrix2D(
2017 Sequence
<double>(4),
2018 rendering::CompositeOperation::SOURCE
);
2020 const double nX1
= nX0
+ nWidth
;
2021 const double nY1
= nY0
+ nHeight
;
2022 for (double nY
=nY0
; nY
<nY1
; nY
+=aSize
.Height
)
2023 for (double nX
=nX0
; nX
<nX1
; nX
+=aSize
.Width
)
2025 aRenderState
.AffineTransform
.m02
= nX
;
2026 aRenderState
.AffineTransform
.m12
= nY
;
2027 rxCanvas
->drawBitmap(
2034 } } // end of namespace ::sdext::presenter
2036 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */