summaryrefslogtreecommitdiff
path: root/sdext/source/presenter/PresenterSlideSorter.cxx
diff options
context:
space:
mode:
authorVladimir Glazounov <vg@openoffice.org>2008-05-13 13:37:48 +0000
committerVladimir Glazounov <vg@openoffice.org>2008-05-13 13:37:48 +0000
commitd3ff78188fd08422586e7a884a31e185ecdde34c (patch)
tree3ceacf4d572e802b80e624ea7b44d3c650acb243 /sdext/source/presenter/PresenterSlideSorter.cxx
parent43a71a2d078a69927db8b492066cc6e176c84f45 (diff)
INTEGRATION: CWS presenterscreen (1.2.4); FILE MERGED
2008/04/28 14:46:33 af 1.2.4.5: #i18486# Fixed GetColumn() and GetRow() for when offsets are not zero. 2008/04/22 13:05:58 af 1.2.4.4: #i18486# Made extension identifier platform specific. 2008/04/22 08:28:04 af 1.2.4.3: RESYNC: (1.2-1.3); FILE MERGED 2008/04/16 16:59:13 af 1.2.4.2: #i18486# Fixed some Linux build problems. 2008/04/16 16:05:13 af 1.2.4.1: #i18486# Added close button. Changed mouse over effect.
Diffstat (limited to 'sdext/source/presenter/PresenterSlideSorter.cxx')
-rw-r--r--sdext/source/presenter/PresenterSlideSorter.cxx1826
1 files changed, 1327 insertions, 499 deletions
diff --git a/sdext/source/presenter/PresenterSlideSorter.cxx b/sdext/source/presenter/PresenterSlideSorter.cxx
index c71c6fa89b6e..aec508f99b8c 100644
--- a/sdext/source/presenter/PresenterSlideSorter.cxx
+++ b/sdext/source/presenter/PresenterSlideSorter.cxx
@@ -8,7 +8,7 @@
*
* $RCSfile: PresenterSlideSorter.cxx,v $
*
- * $Revision: 1.3 $
+ * $Revision: 1.4 $
*
* This file is part of OpenOffice.org.
*
@@ -30,14 +30,20 @@
************************************************************************/
#include "PresenterSlideSorter.hxx"
+#include "PresenterButton.hxx"
+#include "PresenterCanvasHelper.hxx"
+#include "PresenterComponent.hxx"
#include "PresenterGeometryHelper.hxx"
#include "PresenterHelper.hxx"
+#include "PresenterPaintManager.hxx"
+#include "PresenterPaneBase.hxx"
#include "PresenterScrollBar.hxx"
+#include "PresenterUIPainter.hxx"
#include "PresenterWindowManager.hxx"
-#include <com/sun/star/awt/InvalidateStyle.hpp>
#include <com/sun/star/awt/PosSize.hpp>
#include <com/sun/star/awt/XWindowPeer.hpp>
#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XNamed.hpp>
#include <com/sun/star/drawing/XSlideSorterBase.hpp>
#include <com/sun/star/drawing/framework/XConfigurationController.hpp>
#include <com/sun/star/drawing/framework/XControllerManager.hpp>
@@ -54,8 +60,41 @@ using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::drawing::framework;
using ::rtl::OUString;
+#define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString)))
+
+namespace {
+ const static sal_Int32 gnVerticalGap (10);
+ const static sal_Int32 gnVerticalBorder (10);
+ const static sal_Int32 gnHorizontalGap (10);
+ const static sal_Int32 gnHorizontalBorder (10);
+
+ const static double gnMinimalPreviewWidth (200);
+ const static double gnPreferredPreviewWidth (300);
+ const static double gnMaximalPreviewWidth (400);
+ const static sal_Int32 gnPreferredColumnCount (6);
+ const static double gnMinimalHorizontalPreviewGap(15);
+ const static double gnPreferredHorizontalPreviewGap(25);
+ const static double gnMaximalHorizontalPreviewGap(50);
+ const static double gnMinimalVerticalPreviewGap(15);
+ const static double gnPreferredVerticalPreviewGap(25);
+ const static double gnMaximalVerticalPreviewGap(50);
+
+ const static sal_Int32 gnHorizontalLabelBorder (3);
+ const static sal_Int32 gnHorizontalLabelPadding (5);
+
+ const static sal_Int32 gnVerticalButtonPadding (gnVerticalGap);
+}
+
namespace sdext { namespace presenter {
+namespace {
+ sal_Int32 round (const double nValue) { return sal::static_int_cast<sal_Int32>(0.5 + nValue); }
+ sal_Int32 floor (const double nValue) { return sal::static_int_cast<sal_Int32>(nValue); }
+ double sqr (const double nValue) { return nValue*nValue; }
+}
+
+
+
//===== PresenterSlideSorter::Layout ==========================================
class PresenterSlideSorter::Layout
@@ -67,32 +106,38 @@ public:
const ::rtl::Reference<PresenterScrollBar>& rpHorizontalScrollBar,
const ::rtl::Reference<PresenterScrollBar>& rpVerticalScrollBar);
- void Update (const awt::Rectangle& rWindowBox, const double nSlideAspectRatio);
+ void Update (const geometry::RealRectangle2D& rBoundingBox, const double nSlideAspectRatio);
void SetupVisibleArea (void);
- sal_Int32 GetSlideIndexForPosition (const css::geometry::RealPoint2D& rPoint);
+ void UpdateScrollBars (void);
+ bool IsScrollBarNeeded (const sal_Int32 nSlideCount);
+ geometry::RealPoint2D GetLocalPosition (const geometry::RealPoint2D& rWindowPoint) const;
+ geometry::RealPoint2D GetWindowPosition(const geometry::RealPoint2D& rLocalPoint) const;
+ sal_Int32 GetColumn (const geometry::RealPoint2D& rLocalPoint,
+ const bool bReturnInvalidValue = false) const;
+ sal_Int32 GetRow (const geometry::RealPoint2D& rLocalPoint,
+ const bool bReturnInvalidValue = false) const;
+ sal_Int32 GetSlideIndexForPosition (const css::geometry::RealPoint2D& rPoint) const;
css::geometry::RealPoint2D GetPoint (
const sal_Int32 nSlideIndex,
const sal_Int32 nRelativeHorizontalPosition,
- const sal_Int32 nRelativeVerticalPosition);
- enum DistanceType { Norm1, Norm2, XOnly, YOnly };
- double GetDistanceFromCenter (
- const css::geometry::RealPoint2D& rPoint,
- const sal_Int32 nSlideIndex,
- const DistanceType eDistanceType);
- css::awt::Rectangle GetBoundingBox (const sal_Int32 nSlideIndex);
+ const sal_Int32 nRelativeVerticalPosition) const;
+ css::awt::Rectangle GetBoundingBox (const sal_Int32 nSlideIndex) const;
+ geometry::IntegerSize2D GetPreviewSize (void) const;
void ForAllVisibleSlides (const ::boost::function<void(sal_Int32)>& rAction);
- sal_Int32 GetFirstVisibleSlideIndex (void);
- sal_Int32 GetLastVisibleSlideIndex (void);
+ sal_Int32 GetFirstVisibleSlideIndex (void) const;
+ sal_Int32 GetLastVisibleSlideIndex (void) const;
bool SetHorizontalOffset (const double nOffset);
+ bool SetVerticalOffset (const double nOffset);
+ Orientation GetOrientation (void) const;
- css::geometry::RealRectangle2D maInnerBorder;
- css::geometry::RealRectangle2D maOuterBorder;
- css::geometry::RealRectangle2D maViewport;
+ css::geometry::RealRectangle2D maBoundingBox;
css::geometry::IntegerSize2D maPreviewSize;
- double mnHorizontalOffset;
- double mnVerticalOffset;
- double mnHorizontalGap;
- double mnVerticalGap;
+ sal_Int32 mnHorizontalOffset;
+ sal_Int32 mnVerticalOffset;
+ sal_Int32 mnHorizontalGap;
+ sal_Int32 mnVerticalGap;
+ sal_Int32 mnHorizontalBorder;
+ sal_Int32 mnVerticalBorder;
sal_Int32 mnRowCount;
sal_Int32 mnColumnCount;
sal_Int32 mnSlideCount;
@@ -101,16 +146,15 @@ public:
sal_Int32 mnLastVisibleColumn;
sal_Int32 mnFirstVisibleRow;
sal_Int32 mnLastVisibleRow;
- double mnScrollBarHeight;
private:
Orientation meOrientation;
::rtl::Reference<PresenterScrollBar> mpHorizontalScrollBar;
::rtl::Reference<PresenterScrollBar> mpVerticalScrollBar;
- void UpdateScrollBars (void);
- sal_Int32 GetIndex (const sal_Int32 nRow, const sal_Int32 nColumn);
- sal_Int32 GetRow (const sal_Int32 nSlideIndex);
- sal_Int32 GetColumn (const sal_Int32 nSlideIndex);
+
+ sal_Int32 GetIndex (const sal_Int32 nRow, const sal_Int32 nColumn) const;
+ sal_Int32 GetRow (const sal_Int32 nSlideIndex) const;
+ sal_Int32 GetColumn (const sal_Int32 nSlideIndex) const;
};
@@ -118,58 +162,110 @@ private:
//==== PresenterSlideSorter::MouseOverManager =================================
-namespace {
- typedef cppu::WeakComponentImplHelper1<
- css::drawing::XSlidePreviewCacheListener
- > MouseOverManagerInterfaceBase;
-}
-
class PresenterSlideSorter::MouseOverManager
- : private ::cppu::BaseMutex,
- public MouseOverManagerInterfaceBase
+ : ::boost::noncopyable
{
public:
- const static double mnMinScale;
- const static double mnMaxScale;
-
MouseOverManager (
- const Reference<XComponentContext>& rxContext,
const Reference<container::XIndexAccess>& rxSlides,
- const Reference<frame::XModel>& rxModel);
+ const ::boost::shared_ptr<PresenterTheme>& rpTheme,
+ const Reference<awt::XWindow>& rxInvalidateTarget,
+ const ::boost::shared_ptr<PresenterPaintManager>& rpPaintManager);
~MouseOverManager (void);
- void SetCanvas (
- const Reference<rendering::XSpriteCanvas>& rxCanvas);
+ void Paint (
+ const sal_Int32 nSlideIndex,
+ const Reference<rendering::XCanvas>& rxCanvas,
+ const Reference<rendering::XPolyPolygon2D>& rxClip);
void SetSlide (
const sal_Int32 nSlideIndex,
- const awt::Rectangle& rBox,
- const double nDistance);
+ const awt::Rectangle& rBox);
- void SetActiveState (const bool bIsActive);
+private:
+ Reference<rendering::XCanvas> mxCanvas;
+ const Reference<container::XIndexAccess> mxSlides;
+ SharedBitmapDescriptor mpLeftLabelBitmap;
+ SharedBitmapDescriptor mpCenterLabelBitmap;
+ SharedBitmapDescriptor mpRightLabelBitmap;
+ PresenterTheme::SharedFontDescriptor mpFont;
+ sal_Int32 mnSlideIndex;
+ awt::Rectangle maSlideBoundingBox;
+ OUString msText;
+ Reference<rendering::XBitmap> mxBitmap;
+ Reference<awt::XWindow> mxInvalidateTarget;
+ ::boost::shared_ptr<PresenterPaintManager> mpPaintManager;
- // XSlidePreviewCacheListener
+ void SetCanvas (
+ const Reference<rendering::XCanvas>& rxCanvas);
+ /** Create a bitmap that shows the given text and is not wider than the
+ given maximal width.
+ */
+ Reference<rendering::XBitmap> CreateBitmap (
+ const OUString& rsText,
+ const sal_Int32 nMaximalWidth) const;
+ void Invalidate (void);
+ geometry::IntegerSize2D CalculateLabelSize (
+ const OUString& rsText) const;
+ OUString GetFittingText (const OUString& rsText, const double nMaximalWidth) const;
+ void PaintButtonBackground (
+ const Reference<rendering::XBitmapCanvas>& rxCanvas,
+ const geometry::IntegerSize2D& rSize) const;
+};
+
+
+
+
+//==== PresenterSlideSorter::CurrentSlideFrameRenderer ========================
+
+class PresenterSlideSorter::CurrentSlideFrameRenderer
+{
+public:
+ CurrentSlideFrameRenderer (
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext,
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas);
+ ~CurrentSlideFrameRenderer (void);
- virtual void SAL_CALL notifyPreviewCreation (
- sal_Int32 nSlideIndex)
- throw(css::uno::RuntimeException);
+ void PaintCurrentSlideFrame (
+ const awt::Rectangle& rSlideBoundingBox,
+ const Reference<rendering::XCanvas>& rxCanvas,
+ const geometry::RealRectangle2D& rClipBox);
+
+ /** Enlarge the given rectangle to include the current slide indicator.
+ */
+ awt::Rectangle GetBoundingBox (
+ const awt::Rectangle& rSlideBoundingBox);
private:
- Reference<rendering::XSpriteCanvas> mxCanvas;
- Reference<drawing::XSlidePreviewCache> mxPreviewCache;
- sal_Int32 mnSlideIndex;
- awt::Rectangle maBoundingBox;
- double mnDistance;
- Reference<rendering::XCustomSprite> mxSprite;
- geometry::RealSize2D maSpriteSize;
- bool mbIsActive;
-
- void CreateSprite (const sal_Int32 nSlideIndex);
- void DisposeSprite (void);
+ SharedBitmapDescriptor mpTopLeft;
+ SharedBitmapDescriptor mpTop;
+ SharedBitmapDescriptor mpTopRight;
+ SharedBitmapDescriptor mpLeft;
+ SharedBitmapDescriptor mpRight;
+ SharedBitmapDescriptor mpBottomLeft;
+ SharedBitmapDescriptor mpBottom;
+ SharedBitmapDescriptor mpBottomRight;
+ sal_Int32 mnTopFrameSize;
+ sal_Int32 mnLeftFrameSize;
+ sal_Int32 mnRightFrameSize;
+ sal_Int32 mnBottomFrameSize;
+
+ void PaintBitmapOnce(
+ const css::uno::Reference<css::rendering::XBitmap>& rxBitmap,
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
+ const Reference<rendering::XPolyPolygon2D>& rxClip,
+ const double nX,
+ const double nY);
+ void PaintBitmapTiled(
+ const css::uno::Reference<css::rendering::XBitmap>& rxBitmap,
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
+ const geometry::RealRectangle2D& rClipBox,
+ const double nX,
+ const double nY,
+ const double nWidth,
+ const double nHeight);
};
-const double PresenterSlideSorter::MouseOverManager::mnMinScale = 1.0;
-const double PresenterSlideSorter::MouseOverManager::mnMaxScale = 2.0;
@@ -190,11 +286,20 @@ PresenterSlideSorter::PresenterSlideSorter (
mxSlideShowController(mpPresenterController->GetSlideShowController()),
mxPreviewCache(),
mbIsPaintPending(true),
+ mbIsLayoutPending(true),
mpLayout(),
mpHorizontalScrollBar(),
+ mpVerticalScrollBar(),
+ mpCloseButton(),
mpMouseOverManager(),
mnSlideIndexMousePressed(-1),
- mnCurrentSlideIndex(-1)
+ mnCurrentSlideIndex(-1),
+ mnSeparatorY(0),
+ maSeparatorColor(0x00ffffff),
+ maCloseButtonCenter(),
+ maCurrentSlideFrameBoundingBox(),
+ mpCurrentSlideFrameRenderer(),
+ mxPreviewFrame()
{
if ( ! rxContext.is()
|| ! rxViewId.is()
@@ -226,21 +331,48 @@ PresenterSlideSorter::PresenterSlideSorter (
mxWindow->addMouseMotionListener(this);
mxWindow->setVisible(sal_True);
- // Create the scroll bar.
- mpHorizontalScrollBar = ::rtl::Reference<PresenterScrollBar>(
- new PresenterHorizontalScrollBar(
- rxContext,
- mxWindow,
- ::boost::bind(&PresenterSlideSorter::SetHorizontalOffset,this,_1)));
-
// Remember the current slide.
mnCurrentSlideIndex = mxSlideShowController->getCurrentSlideIndex();
+ // Set the orientation.
+ const bool bIsVertical (true);
+
+ // Create the scroll bar.
+ if (bIsVertical)
+ mpVerticalScrollBar = ::rtl::Reference<PresenterScrollBar>(
+ new PresenterVerticalScrollBar(
+ rxContext,
+ mxWindow,
+ mpPresenterController->GetPaintManager(),
+ ::boost::bind(&PresenterSlideSorter::SetVerticalOffset,this,_1)));
+ else
+ mpHorizontalScrollBar = ::rtl::Reference<PresenterScrollBar>(
+ new PresenterHorizontalScrollBar(
+ rxContext,
+ mxWindow,
+ mpPresenterController->GetPaintManager(),
+ ::boost::bind(&PresenterSlideSorter::SetHorizontalOffset,this,_1)));
+ mpCloseButton = PresenterButton::Create(
+ rxContext,
+ mpPresenterController,
+ mpPresenterController->GetTheme(),
+ mxWindow,
+ mxCanvas,
+ A2S("SlideSorterCloser"));
+
+ if (mpPresenterController->GetTheme().get() != NULL)
+ {
+ PresenterTheme::SharedFontDescriptor pFont (
+ mpPresenterController->GetTheme()->GetFont(A2S("ButtonFont")));
+ if (pFont.get() != NULL)
+ maSeparatorColor = pFont->mnColor;
+ }
+
// Create the layout.
mpLayout.reset(new Layout(
- Layout::Horizontal,
+ Layout::Vertical,
mpHorizontalScrollBar,
- ::rtl::Reference<PresenterScrollBar>()));
+ mpVerticalScrollBar));
// Create the preview cache.
mxPreviewCache = Reference<drawing::XSlidePreviewCache>(
@@ -257,10 +389,11 @@ PresenterSlideSorter::PresenterSlideSorter (
}
// Create the mouse over manager.
- mpMouseOverManager = ::rtl::Reference<MouseOverManager>(new MouseOverManager(
- mxComponentContext,
+ mpMouseOverManager.reset(new MouseOverManager(
Reference<container::XIndexAccess>(mxSlideShowController, UNO_QUERY),
- rxController->getModel()));
+ mpPresenterController->GetTheme(),
+ mxWindow,
+ mpPresenterController->GetPaintManager()));
// Listen for changes of the current slide.
Reference<beans::XPropertySet> xControllerProperties (rxController, UNO_QUERY_THROW);
@@ -268,14 +401,10 @@ PresenterSlideSorter::PresenterSlideSorter (
OUString::createFromAscii("CurrentPage"),
this);
- UpdateLayout();
-
// Move the current slide in the center of the window.
const awt::Rectangle aCurrentSlideBBox (mpLayout->GetBoundingBox(mnCurrentSlideIndex));
const awt::Rectangle aWindowBox (mxWindow->getPosSize());
SetHorizontalOffset(aCurrentSlideBBox.X - aWindowBox.Width/2.0);
-
- Paint();
}
catch (RuntimeException&)
{
@@ -299,6 +428,32 @@ void SAL_CALL PresenterSlideSorter::disposing (void)
mxComponentContext = NULL;
mxViewId = NULL;
mxPane = NULL;
+
+ if (mpVerticalScrollBar.is())
+ {
+ Reference<lang::XComponent> xComponent (
+ static_cast<XWeak*>(mpVerticalScrollBar.get()), UNO_QUERY);
+ mpVerticalScrollBar = NULL;
+ if (xComponent.is())
+ xComponent->dispose();
+ }
+ if (mpHorizontalScrollBar.is())
+ {
+ Reference<lang::XComponent> xComponent (
+ static_cast<XWeak*>(mpHorizontalScrollBar.get()), UNO_QUERY);
+ mpHorizontalScrollBar = NULL;
+ if (xComponent.is())
+ xComponent->dispose();
+ }
+ if (mpCloseButton.is())
+ {
+ Reference<lang::XComponent> xComponent (
+ static_cast<XWeak*>(mpCloseButton.get()), UNO_QUERY);
+ mpCloseButton = NULL;
+ if (xComponent.is())
+ xComponent->dispose();
+ }
+
if (mxCanvas.is())
{
Reference<lang::XComponent> xComponent (mxCanvas, UNO_QUERY);
@@ -309,12 +464,7 @@ void SAL_CALL PresenterSlideSorter::disposing (void)
mpPresenterController = NULL;
mxSlideShowController = NULL;
mpLayout.reset();
- mpHorizontalScrollBar = NULL;
- if (mpMouseOverManager.is())
- {
- mpMouseOverManager->dispose();
- mpMouseOverManager = NULL;
- }
+ mpMouseOverManager.reset();
if (mxPreviewCache.is())
{
@@ -340,14 +490,7 @@ void SAL_CALL PresenterSlideSorter::disposing (void)
void PresenterSlideSorter::SetActiveState (const bool bIsActive)
{
- if (mxPreviewCache.is())
- if (bIsActive)
- mxPreviewCache->resume();
- else
- mxPreviewCache->pause();
-
- if (mpMouseOverManager.get() != NULL)
- mpMouseOverManager->SetActiveState(bIsActive);
+ (void)bIsActive;
}
@@ -371,15 +514,12 @@ void SAL_CALL PresenterSlideSorter::disposing (const lang::EventObject& rEventOb
else if (rEventObject.Source == mxCanvas)
{
mxCanvas = NULL;
- if (mpMouseOverManager.get() != NULL)
- mpMouseOverManager->SetCanvas(NULL);
if (mpHorizontalScrollBar.is())
mpHorizontalScrollBar->SetCanvas(NULL);
+ mbIsLayoutPending = true;
mbIsPaintPending = true;
- Reference<awt::XWindowPeer> xPeer (mxWindow, UNO_QUERY);
- if (xPeer.is())
- xPeer->invalidate(awt::InvalidateStyle::CHILDREN);
+ mpPresenterController->GetPaintManager()->Invalidate(mxWindow);
}
}
@@ -393,9 +533,8 @@ void SAL_CALL PresenterSlideSorter::windowResized (const awt::WindowEvent& rEven
{
(void)rEvent;
ThrowIfDisposed();
- // The canvas should eventually be (or already has been) disposed by the
- // pane. We listen for that and request a repaint when that happens.
- mbIsPaintPending = true;
+ mbIsLayoutPending = true;
+ mpPresenterController->GetPaintManager()->Invalidate(mxWindow);
}
@@ -416,7 +555,8 @@ void SAL_CALL PresenterSlideSorter::windowShown (const lang::EventObject& rEvent
{
(void)rEvent;
ThrowIfDisposed();
- mbIsPaintPending = true;
+ mbIsLayoutPending = true;
+ mpPresenterController->GetPaintManager()->Invalidate(mxWindow);
}
@@ -439,20 +579,15 @@ void SAL_CALL PresenterSlideSorter::windowPaint (const css::awt::PaintEvent& rEv
{
(void)rEvent;
- if ( ! ProvideCanvas())
+ // Deactivated views must not be painted.
+ if ( ! mbIsPresenterViewActive)
return;
- if (mbIsPaintPending)
- {
- UpdateLayout();
- Paint();
- }
+ Paint(rEvent.UpdateRect);
- /*
Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY);
if (xSpriteCanvas.is())
xSpriteCanvas->updateScreen(sal_False);
- */
}
@@ -478,8 +613,20 @@ void SAL_CALL PresenterSlideSorter::mouseReleased (const css::awt::MouseEvent& r
if (nSlideIndex == mnSlideIndexMousePressed && mnSlideIndexMousePressed >= 0)
{
- mpMouseOverManager->SetSlide(-1, awt::Rectangle(0,0,0,0), 0);
- GotoSlide(nSlideIndex);
+ switch (rEvent.ClickCount)
+ {
+ case 1:
+ default:
+ GotoSlide(nSlideIndex);
+ break;
+
+ case 2:
+ OSL_ASSERT(mpPresenterController.get()!=NULL);
+ OSL_ASSERT(mpPresenterController->GetWindowManager().get()!=NULL);
+ mpPresenterController->GetWindowManager()->SetSlideSorterState(false);
+ GotoSlide(nSlideIndex);
+ break;
+ }
}
}
@@ -501,7 +648,7 @@ void SAL_CALL PresenterSlideSorter::mouseExited (const css::awt::MouseEvent& rEv
(void)rEvent;
mnSlideIndexMousePressed = -1;
if (mpMouseOverManager.get() != NULL)
- mpMouseOverManager->SetSlide(mnSlideIndexMousePressed, awt::Rectangle(0,0,0,0), 0);
+ mpMouseOverManager->SetSlide(mnSlideIndexMousePressed, awt::Rectangle(0,0,0,0));
}
@@ -516,32 +663,19 @@ void SAL_CALL PresenterSlideSorter::mouseMoved (const css::awt::MouseEvent& rEve
{
const geometry::RealPoint2D aPosition (rEvent.X, rEvent.Y);
sal_Int32 nSlideIndex (mpLayout->GetSlideIndexForPosition(aPosition));
- double nDistanceFromCenter (2);
- if (nSlideIndex >= 0)
- {
- const double nDistance (mpLayout->GetDistanceFromCenter(aPosition, nSlideIndex,
- Layout::Norm1));
- if (nDistance < 1)
- nDistanceFromCenter = nDistance;
- else
- nSlideIndex = -1;
- }
- else
- {
+ if (nSlideIndex < 0)
mnSlideIndexMousePressed = -1;
- }
if (nSlideIndex < 0)
{
- mpMouseOverManager->SetSlide(nSlideIndex, awt::Rectangle(0,0,0,0), 0);
+ mpMouseOverManager->SetSlide(nSlideIndex, awt::Rectangle(0,0,0,0));
}
else
{
mpMouseOverManager->SetSlide(
nSlideIndex,
- mpLayout->GetBoundingBox(nSlideIndex),
- nDistanceFromCenter);
+ mpLayout->GetBoundingBox(nSlideIndex));
}
}
}
@@ -586,7 +720,6 @@ void SAL_CALL PresenterSlideSorter::propertyChange (
throw(css::uno::RuntimeException)
{
(void)rEvent;
- // Close the slide sorter view.
}
@@ -598,7 +731,57 @@ void SAL_CALL PresenterSlideSorter::notifyPreviewCreation (
sal_Int32 nSlideIndex)
throw(css::uno::RuntimeException)
{
- PaintPreview(nSlideIndex);
+ OSL_ASSERT(mpLayout.get()!=NULL);
+
+ awt::Rectangle aBBox (mpLayout->GetBoundingBox(nSlideIndex));
+ mpPresenterController->GetPaintManager()->Invalidate(mxWindow, aBBox, true);
+}
+
+
+
+
+//----- XDrawView -------------------------------------------------------------
+
+void SAL_CALL PresenterSlideSorter::setCurrentPage (const Reference<drawing::XDrawPage>& rxSlide)
+ throw (RuntimeException)
+{
+ (void)rxSlide;
+
+ ThrowIfDisposed();
+ ::osl::MutexGuard aGuard (::osl::Mutex::getGlobalMutex());
+
+ if (mxSlideShowController.is())
+ {
+ const sal_Int32 nNewCurrentSlideIndex (mxSlideShowController->getCurrentSlideIndex());
+ if (nNewCurrentSlideIndex != mnCurrentSlideIndex)
+ {
+ mnCurrentSlideIndex = nNewCurrentSlideIndex;
+
+ // Request a repaint of the previous current slide to hide its
+ // current slide indicator.
+ mpPresenterController->GetPaintManager()->Invalidate(
+ mxWindow,
+ maCurrentSlideFrameBoundingBox);
+
+ // Request a repaint of the new current slide to show its
+ // current slide indicator.
+ maCurrentSlideFrameBoundingBox = mpCurrentSlideFrameRenderer->GetBoundingBox(
+ mpLayout->GetBoundingBox(mnCurrentSlideIndex));
+ mpPresenterController->GetPaintManager()->Invalidate(
+ mxWindow,
+ maCurrentSlideFrameBoundingBox);
+ }
+ }
+}
+
+
+
+
+Reference<drawing::XDrawPage> SAL_CALL PresenterSlideSorter::getCurrentPage (void)
+ throw (RuntimeException)
+{
+ ThrowIfDisposed();
+ return NULL;
}
@@ -611,15 +794,162 @@ void PresenterSlideSorter::UpdateLayout (void)
if ( ! mxWindow.is())
return;
- mpLayout->Update(
- mxWindow->getPosSize(),
- GetSlideAspectRatio());
+ mbIsLayoutPending = false;
+ mbIsPaintPending = true;
+
+ const awt::Rectangle aWindowBox (mxWindow->getPosSize());
+ awt::Rectangle aCenterBox (aWindowBox);
+ sal_Int32 nLeftBorderWidth (aWindowBox.X);
+
+ // Get border width.
+ PresenterPaneContainer::SharedPaneDescriptor pPane (
+ mpPresenterController->GetPaneContainer()->FindViewURL(
+ mxViewId->getResourceURL()));
+ do
+ {
+ if (pPane.get() == NULL)
+ break;
+ if ( ! pPane->mxPane.is())
+ break;
+
+ Reference<drawing::framework::XPaneBorderPainter> xBorderPainter (
+ pPane->mxPane->GetPaneBorderPainter());
+ if ( ! xBorderPainter.is())
+ break;
+ aCenterBox = xBorderPainter->addBorder (
+ mxViewId->getAnchor()->getResourceURL(),
+ awt::Rectangle(0, 0, aWindowBox.Width, aWindowBox.Height),
+ drawing::framework::BorderType_INNER_BORDER);
+ }
+ while(false);
+
+ // Place vertical separator.
+ mnSeparatorY = aWindowBox.Height - mpCloseButton->GetSize().Height - gnVerticalButtonPadding;
+
+ PlaceCloseButton(pPane, aWindowBox, nLeftBorderWidth);
+
+ geometry::RealRectangle2D aUpperBox(
+ gnHorizontalBorder,
+ gnVerticalBorder,
+ aWindowBox.Width - 2*gnHorizontalBorder,
+ mnSeparatorY - gnVerticalGap);
+
+ // Determine whether the scroll bar has to be displayed.
+ aUpperBox = PlaceScrollBars(aUpperBox);
+
+ mpLayout->Update(aUpperBox, GetSlideAspectRatio());
+ mpLayout->SetupVisibleArea();
+ mpLayout->UpdateScrollBars();
// Tell the preview cache about some of the values.
mxPreviewCache->setPreviewSize(mpLayout->maPreviewSize);
mxPreviewCache->setVisibleRange(
mpLayout->GetFirstVisibleSlideIndex(),
mpLayout->GetLastVisibleSlideIndex());
+
+ // Clear the frame polygon so that it is re-created on the next paint.
+ mxPreviewFrame = NULL;
+}
+
+
+
+
+geometry::RealRectangle2D PresenterSlideSorter::PlaceScrollBars (
+ const geometry::RealRectangle2D& rUpperBox)
+{
+ mpLayout->Update(rUpperBox, GetSlideAspectRatio());
+ bool bIsScrollBarNeeded (false);
+ Reference<container::XIndexAccess> xSlides (mxSlideShowController, UNO_QUERY_THROW);
+ if (xSlides.is())
+ bIsScrollBarNeeded = mpLayout->IsScrollBarNeeded(xSlides->getCount());
+
+ if (mpLayout->GetOrientation() == Layout::Vertical)
+ {
+ if (mpVerticalScrollBar.get() != NULL)
+ {
+ if (bIsScrollBarNeeded)
+ {
+ // Place vertical scroll bar at right border.
+ mpVerticalScrollBar->SetPosSize(geometry::RealRectangle2D(
+ rUpperBox.X2 - mpVerticalScrollBar->GetSize(),
+ rUpperBox.Y1,
+ rUpperBox.X2,
+ rUpperBox.Y2));
+ mpVerticalScrollBar->SetVisible(true);
+
+ // Reduce area covered by the scroll bar from the available
+ // space.
+ return geometry::RealRectangle2D(
+ rUpperBox.X1,
+ rUpperBox.Y1,
+ rUpperBox.X2 - mpVerticalScrollBar->GetSize() - gnHorizontalGap,
+ rUpperBox.Y2);
+ }
+ else
+ mpVerticalScrollBar->SetVisible(false);
+ }
+ }
+ else
+ {
+ if (mpHorizontalScrollBar.get() != NULL)
+ {
+ if (bIsScrollBarNeeded)
+ {
+ // Place horixontal scroll bar at the bottom.
+ mpHorizontalScrollBar->SetPosSize(geometry::RealRectangle2D(
+ rUpperBox.X1,
+ rUpperBox.Y2 - mpHorizontalScrollBar->GetSize(),
+ rUpperBox.X2,
+ rUpperBox.Y2));
+ mpHorizontalScrollBar->SetVisible(true);
+
+ // Reduce area covered by the scroll bar from the available
+ // space.
+ return geometry::RealRectangle2D(
+ rUpperBox.X1,
+ rUpperBox.Y1,
+ rUpperBox.X2,
+ rUpperBox.Y2 - mpHorizontalScrollBar->GetSize() - gnVerticalGap);
+ }
+ else
+ mpHorizontalScrollBar->SetVisible(false);
+ }
+ }
+
+ return rUpperBox;
+}
+
+
+
+
+void PresenterSlideSorter::PlaceCloseButton (
+ const PresenterPaneContainer::SharedPaneDescriptor& rpPane,
+ const awt::Rectangle& rCenterBox,
+ const sal_Int32 nLeftBorderWidth)
+{
+ // Place button. When the callout is near the center then the button is
+ // centered over the callout. Otherwise it is centered with respect to
+ // the whole window.
+ sal_Int32 nCloseButtonCenter (rCenterBox.Width/2);
+ if (rpPane.get() != NULL && rpPane->mxPane.is())
+ {
+ const sal_Int32 nCalloutCenter (rpPane->mxPane->GetCalloutAnchor().X - nLeftBorderWidth);
+ const sal_Int32 nDistanceFromWindowCenter (abs(nCalloutCenter - rCenterBox.Width/2));
+ const sal_Int32 nButtonWidth (mpCloseButton->GetSize().Width);
+ const static sal_Int32 nMaxDistanceForCalloutCentering (nButtonWidth * 2);
+ if (nDistanceFromWindowCenter < nMaxDistanceForCalloutCentering)
+ {
+ if (nCalloutCenter < nButtonWidth/2)
+ nCloseButtonCenter = nButtonWidth/2;
+ else if (nCalloutCenter > rCenterBox.Width-nButtonWidth/2)
+ nCloseButtonCenter = rCenterBox.Width-nButtonWidth/2;
+ else
+ nCloseButtonCenter = nCalloutCenter;
+ }
+ }
+ mpCloseButton->SetCenter(geometry::RealPoint2D(
+ nCloseButtonCenter,
+ rCenterBox.Height - mpCloseButton->GetSize().Height/ 2));
}
@@ -631,30 +961,13 @@ void PresenterSlideSorter::ClearBackground (
{
OSL_ASSERT(rxCanvas.is());
- util::Color aColor (
- mpPresenterController->GetViewBackgroundColor(mxViewId->getResourceURL()));
- Sequence<double> aBackgroundColor(3);
- aBackgroundColor[0] = ((aColor >> 16) & 0x0ff) / 255.0;
- aBackgroundColor[1] = ((aColor >> 8) & 0x0ff) / 255.0;
- aBackgroundColor[2] = ((aColor >> 0) & 0x0ff) / 255.0;
-
- rendering::ViewState aViewState(
- geometry::AffineMatrix2D(1,0,0, 0,1,0),
- NULL);
-
- rendering::RenderState aRenderState (
- geometry::AffineMatrix2D(1,0,0, 0,1,0),
- NULL,
- aBackgroundColor,
- rendering::CompositeOperation::SOURCE);
-
- Reference<rendering::XPolyPolygon2D> xPolygon (
- PresenterGeometryHelper::CreatePolygon(rUpdateBox, rxCanvas->getDevice()));
- if (xPolygon.is())
- rxCanvas->fillPolyPolygon(
- xPolygon,
- aViewState,
- aRenderState);
+ const awt::Rectangle aWindowBox (mxWindow->getPosSize());
+ mpPresenterController->GetCanvasHelper()->Paint(
+ mpPresenterController->GetViewBackground(mxViewId->getResourceURL()),
+ rxCanvas,
+ rUpdateBox,
+ awt::Rectangle(0,0,aWindowBox.Width,aWindowBox.Height),
+ awt::Rectangle());
}
@@ -705,34 +1018,40 @@ Reference<rendering::XBitmap> PresenterSlideSorter::GetPreview (const sal_Int32
void PresenterSlideSorter::PaintPreview (
+ const Reference<rendering::XCanvas>& rxCanvas,
+ const css::awt::Rectangle& rUpdateBox,
const sal_Int32 nSlideIndex)
{
- if ( ! ProvideCanvas())
- return;
+ OSL_ASSERT(rxCanvas.is());
- const awt::Rectangle aWindowBox (mxWindow->getPosSize());
- PaintPreview(mxCanvas, nSlideIndex);
+ geometry::IntegerSize2D aSize (mpLayout->maPreviewSize);
- Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY);
- if (xSpriteCanvas.is())
- xSpriteCanvas->updateScreen(sal_False);
-}
+ if (PresenterGeometryHelper::AreRectanglesDisjoint(
+ rUpdateBox,
+ mpLayout->GetBoundingBox(nSlideIndex)))
+ {
+ return;
+ }
+ Reference<rendering::XBitmap> xPreview (GetPreview(nSlideIndex));
+ const geometry::RealPoint2D aTopLeft (
+ mpLayout->GetWindowPosition(
+ mpLayout->GetPoint(nSlideIndex, -1, -1)));
+ // Create clip rectangle as intersection of the current update area and
+ // the bounding box of all previews.
+ geometry::RealRectangle2D aBoundingBox (mpLayout->maBoundingBox);
+ aBoundingBox.Y2 += 1;
+ const geometry::RealRectangle2D aClipBox (
+ PresenterGeometryHelper::Intersection(
+ PresenterGeometryHelper::ConvertRectangle(rUpdateBox),
+ aBoundingBox));
+ Reference<rendering::XPolyPolygon2D> xClip (
+ PresenterGeometryHelper::CreatePolygon(aClipBox, rxCanvas->getDevice()));
-void PresenterSlideSorter::PaintPreview (
- const Reference<rendering::XCanvas>& rxCanvas,
- const sal_Int32 nSlideIndex)
-{
- OSL_ASSERT(rxCanvas.is());
-
- Reference<rendering::XBitmap> xPreview (GetPreview(nSlideIndex));
+ const rendering::ViewState aViewState (geometry::AffineMatrix2D(1,0,0, 0,1,0), xClip);
- const geometry::RealPoint2D aTopLeft (mpLayout->GetPoint(nSlideIndex, -1, -1));
- rendering::ViewState aViewState(
- geometry::AffineMatrix2D(1,0,0, 0,1,0),
- NULL);
rendering::RenderState aRenderState (
geometry::AffineMatrix2D(
@@ -742,28 +1061,27 @@ void PresenterSlideSorter::PaintPreview (
Sequence<double>(3),
rendering::CompositeOperation::SOURCE);
- geometry::IntegerSize2D aSize (mpLayout->maPreviewSize);
+ // Emphasize the current slide.
if (nSlideIndex == mnCurrentSlideIndex)
{
- // Paint a frame around the slide preview that indicates that this
- // is the current slide.
- const double nFrameWidth (3);
- const geometry::RealRectangle2D aBox (-nFrameWidth, -nFrameWidth,
- aSize.Width+nFrameWidth, aSize.Height+nFrameWidth);
- Reference<rendering::XPolyPolygon2D> xPolygon (
- PresenterGeometryHelper::CreatePolygon(aBox, rxCanvas->getDevice()));
- if (xPolygon.is())
+ if (mpCurrentSlideFrameRenderer.get() != NULL)
{
- const util::Color aColor (
- mpPresenterController->GetViewFontColor(mxViewId->getResourceURL()));
- aRenderState.DeviceColor[0] = ((aColor >> 16) & 0x0ff) / 255.0;
- aRenderState.DeviceColor[1] = ((aColor >> 8) & 0x0ff) / 255.0;
- aRenderState.DeviceColor[2] = ((aColor >> 0) & 0x0ff) / 255.0;
- rxCanvas->fillPolyPolygon(xPolygon, aViewState, aRenderState);
+ const awt::Rectangle aSlideBoundingBox(
+ sal::static_int_cast<sal_Int32>(0.5 + aTopLeft.X),
+ sal::static_int_cast<sal_Int32>(0.5 + aTopLeft.Y),
+ aSize.Width,
+ aSize.Height);
+ maCurrentSlideFrameBoundingBox
+ = mpCurrentSlideFrameRenderer->GetBoundingBox(aSlideBoundingBox);
+ mpCurrentSlideFrameRenderer->PaintCurrentSlideFrame (
+ aSlideBoundingBox,
+ mxCanvas,
+ aClipBox);
}
}
+ // Paint the preview.
if (xPreview.is())
{
aSize = xPreview->getSize();
@@ -773,26 +1091,32 @@ void PresenterSlideSorter::PaintPreview (
}
}
+ // Create a polygon that is used to paint a frame around previews. Its
+ // coordinates are chosen in the local coordinate system of a preview.
+ if ( ! mxPreviewFrame.is())
+ mxPreviewFrame = PresenterGeometryHelper::CreatePolygon(
+ awt::Rectangle(-1, -1, aSize.Width+2, aSize.Height+2),
+ rxCanvas->getDevice());
+
// Paint a border around the preview.
- const geometry::RealRectangle2D aBox (0, 0, aSize.Width, aSize.Height);
- Reference<rendering::XPolyPolygon2D> xPolygon (
- PresenterGeometryHelper::CreatePolygon(aBox, rxCanvas->getDevice()));
- if (xPolygon.is())
+ if (mxPreviewFrame.is())
{
- const util::Color aColor (
- mpPresenterController->GetViewFontColor(mxViewId->getResourceURL()));
- aRenderState.DeviceColor[0] = ((aColor >> 16) & 0x0ff) / 255.0;
- aRenderState.DeviceColor[1] = ((aColor >> 8) & 0x0ff) / 255.0;
- aRenderState.DeviceColor[2] = ((aColor >> 0) & 0x0ff) / 255.0;
- rxCanvas->drawPolyPolygon(xPolygon, aViewState, aRenderState);
+ const geometry::RealRectangle2D aBox (0, 0, aSize.Width, aSize.Height);
+ const util::Color aFrameColor (0x00000000);
+ PresenterCanvasHelper::SetDeviceColor(aRenderState, aFrameColor);
+ rxCanvas->drawPolyPolygon(mxPreviewFrame, aViewState, aRenderState);
}
+
+ // Paint mouse over effect.
+ mpMouseOverManager->Paint(nSlideIndex, mxCanvas, xClip);
}
-void PresenterSlideSorter::Paint (void)
+void PresenterSlideSorter::Paint (const awt::Rectangle& rUpdateBox)
{
+ const bool bCanvasChanged ( ! mxCanvas.is());
if ( ! ProvideCanvas())
return;
@@ -804,19 +1128,41 @@ void PresenterSlideSorter::Paint (void)
mbIsPaintPending = false;
- const awt::Rectangle aWindowBox (mxWindow->getPosSize());
- ClearBackground(mxCanvas, awt::Rectangle(0,0,aWindowBox.Width,aWindowBox.Height));
+ ClearBackground(mxCanvas, rUpdateBox);
- // Paint the horizontal scroll bar.
- if (mpHorizontalScrollBar.is())
+ // Give the canvas to the controls.
+ if (bCanvasChanged)
{
- mpHorizontalScrollBar->SetCanvas(mxCanvas);
- mpHorizontalScrollBar->Paint(aWindowBox);
+ if (mpHorizontalScrollBar.is())
+ mpHorizontalScrollBar->SetCanvas(mxCanvas);
+ if (mpVerticalScrollBar.is())
+ mpVerticalScrollBar->SetCanvas(mxCanvas);
+ if (mpCloseButton.is())
+ mpCloseButton->SetCanvas(mxCanvas, mxWindow);
}
+ // Now that the controls have a canvas we can do the layouting.
+ if (mbIsLayoutPending)
+ UpdateLayout();
+
+ // Paint the horizontal separator.
+ rendering::RenderState aRenderState (geometry::AffineMatrix2D(1,0,0, 0,1,0),
+ NULL, Sequence<double>(3), rendering::CompositeOperation::SOURCE);
+ PresenterCanvasHelper::SetDeviceColor(aRenderState, maSeparatorColor);
+ mxCanvas->drawLine(
+ geometry::RealPoint2D(0, mnSeparatorY),
+ geometry::RealPoint2D(mxWindow->getPosSize().Width, mnSeparatorY),
+ rendering::ViewState(geometry::AffineMatrix2D(1,0,0, 0,1,0), NULL),
+ aRenderState);
+
// Paint the slides.
- mpLayout->ForAllVisibleSlides(
- ::boost::bind(&PresenterSlideSorter::PaintPreview, this, mxCanvas, _1));
+ if ( ! PresenterGeometryHelper::AreRectanglesDisjoint(
+ rUpdateBox,
+ PresenterGeometryHelper::ConvertRectangle(mpLayout->maBoundingBox)))
+ {
+ mpLayout->ForAllVisibleSlides(
+ ::boost::bind(&PresenterSlideSorter::PaintPreview, this, mxCanvas, rUpdateBox, _1));
+ }
Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY);
if (xSpriteCanvas.is())
@@ -826,25 +1172,30 @@ void PresenterSlideSorter::Paint (void)
-void PresenterSlideSorter::Invalidate (const awt::Rectangle& rBBox)
+void PresenterSlideSorter::SetHorizontalOffset (const double nXOffset)
{
- Reference<awt::XWindowPeer> xPeer (mxWindow, UNO_QUERY);
- if (xPeer.is())
- xPeer->invalidateRect(rBBox, awt::InvalidateStyle::UPDATE);
+ if (mpLayout->SetHorizontalOffset(nXOffset))
+ {
+ mxPreviewCache->setVisibleRange(
+ mpLayout->GetFirstVisibleSlideIndex(),
+ mpLayout->GetLastVisibleSlideIndex());
+
+ mpPresenterController->GetPaintManager()->Invalidate(mxWindow);
+ }
}
-void PresenterSlideSorter::SetHorizontalOffset (const double nXOffset)
+void PresenterSlideSorter::SetVerticalOffset (const double nYOffset)
{
- if (mpLayout->SetHorizontalOffset(nXOffset))
+ if (mpLayout->SetVerticalOffset(nYOffset))
{
mxPreviewCache->setVisibleRange(
mpLayout->GetFirstVisibleSlideIndex(),
mpLayout->GetLastVisibleSlideIndex());
- Paint();
+ mpPresenterController->GetPaintManager()->Invalidate(mxWindow);
}
}
@@ -873,14 +1224,12 @@ bool PresenterSlideSorter::ProvideCanvas (void)
if (xComponent.is())
xComponent->addEventListener(static_cast<awt::XWindowListener*>(this));
- // New canvas => new MouseOverManager.
- if (mpMouseOverManager.get() != NULL)
- mpMouseOverManager->SetCanvas(
- Reference<rendering::XSpriteCanvas>(mxCanvas, UNO_QUERY));
-
// Tell the scrollbar about the canvas.
if (mpHorizontalScrollBar.is())
mpHorizontalScrollBar->SetCanvas(mxCanvas);
+
+ mpCurrentSlideFrameRenderer.reset(
+ new CurrentSlideFrameRenderer(mxComponentContext, mxCanvas));
}
return mxCanvas.is();
}
@@ -888,6 +1237,13 @@ bool PresenterSlideSorter::ProvideCanvas (void)
+void PresenterSlideSorter::Close (void)
+{
+}
+
+
+
+
void PresenterSlideSorter::ThrowIfDisposed (void)
throw (lang::DisposedException)
{
@@ -909,14 +1265,14 @@ PresenterSlideSorter::Layout::Layout (
const Orientation eOrientation,
const ::rtl::Reference<PresenterScrollBar>& rpHorizontalScrollBar,
const ::rtl::Reference<PresenterScrollBar>& rpVerticalScrollBar)
- : maInnerBorder(),
- maOuterBorder(),
- maViewport(),
+ : maBoundingBox(),
maPreviewSize(),
mnHorizontalOffset(0),
mnVerticalOffset(0),
mnHorizontalGap(0),
mnVerticalGap(0),
+ mnHorizontalBorder(0),
+ mnVerticalBorder(0),
mnRowCount(1),
mnColumnCount(1),
mnSlideCount(0),
@@ -925,7 +1281,6 @@ PresenterSlideSorter::Layout::Layout (
mnLastVisibleColumn(-1),
mnFirstVisibleRow(-1),
mnLastVisibleRow(-1),
- mnScrollBarHeight(25),
meOrientation(eOrientation),
mpHorizontalScrollBar(rpHorizontalScrollBar),
mpVerticalScrollBar(rpVerticalScrollBar)
@@ -936,79 +1291,109 @@ PresenterSlideSorter::Layout::Layout (
void PresenterSlideSorter::Layout::Update (
- const awt::Rectangle& rWindowBox,
+ const geometry::RealRectangle2D& rBoundingBox,
const double nSlideAspectRatio)
{
- if (rWindowBox.Width <= 0 || rWindowBox.Height <= 0)
+ maBoundingBox = rBoundingBox;
+
+ mnHorizontalBorder = gnHorizontalBorder;
+ mnVerticalBorder = gnVerticalBorder;
+
+ const double nWidth (rBoundingBox.X2 - rBoundingBox.X1 - 2*mnHorizontalBorder);
+ const double nHeight (rBoundingBox.Y2 - rBoundingBox.Y1 - 2*mnVerticalBorder);
+ if (nWidth<=0 || nHeight<=0)
return;
- const static sal_Int32 nFrameSize (10);
- maInnerBorder = geometry::RealRectangle2D(nFrameSize,nFrameSize,nFrameSize,nFrameSize);
- maOuterBorder = geometry::RealRectangle2D(50,50,50,50);
- const static double nMinGap(15);
- mnRowCount = 1;
- mnColumnCount = 6;
-
- maViewport = geometry::RealRectangle2D(
- maInnerBorder.X1 + maOuterBorder.X1,
- maInnerBorder.Y1 + maInnerBorder.Y1,
- rWindowBox.Width - maInnerBorder.X2 - maOuterBorder.X2,
- rWindowBox.Height - maInnerBorder.Y2 - mnScrollBarHeight - maOuterBorder.Y2);
- const double nAvailableWidth (maViewport.X2 - maViewport.X1);
- const double nAvailableHeight (maViewport.Y2 - maViewport.Y1);
- const double nMaxWidth (::std::max(nAvailableWidth / mnColumnCount - nMinGap, 50.0));
- const double nMaxHeight (::std::max(nAvailableHeight / mnRowCount - nMinGap, 30.0));
-
- // Calculate the preview size.
- if ((double(nMaxWidth) / double(nMaxHeight)) <= nSlideAspectRatio)
- {
- maPreviewSize.Width = sal_Int32(nMaxWidth);
- maPreviewSize.Height = sal_Int32(nMaxWidth / nSlideAspectRatio);
+ double nPreviewWidth;
+
+ // Determine column count, preview width, and horizontal gap (borders
+ // are half the gap). Try to use the preferred values. Try more to
+ // stay in the valid intervalls. This last constraint may be not
+ // fullfilled in some cases.
+ const double nElementWidth = nWidth / gnPreferredColumnCount;
+ if (nElementWidth < gnMinimalPreviewWidth + gnMinimalHorizontalPreviewGap)
+ {
+ // The preferred column count is too large.
+ // Can we use the preferred preview width?
+ if (nWidth - gnMinimalHorizontalPreviewGap >= gnPreferredPreviewWidth)
+ {
+ // Yes.
+ nPreviewWidth = gnPreferredPreviewWidth;
+ mnColumnCount = floor((nWidth+gnPreferredHorizontalPreviewGap)
+ / (nPreviewWidth+gnPreferredHorizontalPreviewGap));
+ mnHorizontalGap = round((nWidth - mnColumnCount*nPreviewWidth) / mnColumnCount);
+ }
+ else
+ {
+ // No. Set the column count to 1 and adapt preview width and
+ // gap.
+ mnColumnCount = 1;
+ mnHorizontalGap = floor(gnMinimalHorizontalPreviewGap);
+ if (nWidth - gnMinimalHorizontalPreviewGap >= gnPreferredPreviewWidth)
+ nPreviewWidth = nWidth - gnMinimalHorizontalPreviewGap;
+ else
+ nPreviewWidth = ::std::max(gnMinimalPreviewWidth, nWidth-mnHorizontalGap);
+ }
+ }
+ else if (nElementWidth > gnMaximalPreviewWidth + gnMaximalHorizontalPreviewGap)
+ {
+ // The preferred column count is too small.
+ nPreviewWidth = gnPreferredPreviewWidth;
+ mnColumnCount = floor((nWidth+gnPreferredHorizontalPreviewGap)
+ / (nPreviewWidth+gnPreferredHorizontalPreviewGap));
+ mnHorizontalGap = round((nWidth - mnColumnCount*nPreviewWidth) / mnColumnCount);
}
else
{
- maPreviewSize.Width = sal_Int32(nMaxHeight * nSlideAspectRatio);
- maPreviewSize.Height = sal_Int32(nMaxHeight);
+ // The preferred column count is possible. Determine gap and
+ // preview width.
+ mnColumnCount = gnPreferredColumnCount;
+ if (nElementWidth - gnPreferredPreviewWidth < gnMinimalHorizontalPreviewGap)
+ {
+ // Use the minimal gap and adapt the preview width.
+ mnHorizontalGap = floor(gnMinimalHorizontalPreviewGap);
+ nPreviewWidth = (nWidth - mnColumnCount*mnHorizontalGap) / mnColumnCount;
+ }
+ else if (nElementWidth - gnPreferredPreviewWidth <= gnMaximalHorizontalPreviewGap)
+ {
+ // Use the maximal gap and adapt the preview width.
+ mnHorizontalGap = round(gnMaximalHorizontalPreviewGap);
+ nPreviewWidth = (nWidth - mnColumnCount*mnHorizontalGap) / mnColumnCount;
+ }
+ else
+ {
+ // Use the preferred preview width and adapt the gap.
+ nPreviewWidth = gnPreferredPreviewWidth;
+ mnHorizontalGap = round((nWidth - mnColumnCount*nPreviewWidth) / mnColumnCount);
+ }
}
- if (maPreviewSize.Width <= 0 || maPreviewSize.Height <= 0)
- return;
- // Calculate the numbers of visible rows and columns.
- mnColumnCount = sal_Int32((nAvailableWidth+nMinGap) / (maPreviewSize.Width + nMinGap));
- if (mnColumnCount < 1)
- mnColumnCount = 1;
- mnRowCount = sal_Int32((nAvailableHeight+nMinGap) / (maPreviewSize.Height + nMinGap));
- if (mnRowCount < 1)
- mnRowCount = 1;
-
- // Calculate the gaps between adjacent previews.
- if (mnColumnCount >= 2)
- mnHorizontalGap = (nAvailableWidth - mnColumnCount*maPreviewSize.Width) / (mnColumnCount-1);
- else
- mnHorizontalGap = 0;
- if (mnRowCount >= 2)
- mnVerticalGap = (nAvailableHeight - mnRowCount*maPreviewSize.Height) / (mnRowCount-1);
- else
- mnVerticalGap = 0;
+ // Now determine the row count, preview height, and vertical gap.
+ const double nPreviewHeight = nPreviewWidth / nSlideAspectRatio;
+ mnRowCount = ::std::max(
+ sal_Int32(1),
+ sal_Int32(ceil((nHeight+gnPreferredVerticalPreviewGap)
+ / (nPreviewHeight + gnPreferredVerticalPreviewGap))));
+ mnVerticalGap = round(gnPreferredVerticalPreviewGap);
+
+ maPreviewSize = geometry::IntegerSize2D(floor(nPreviewWidth), floor(nPreviewHeight));
// Reset the offset.
if (meOrientation == Horizontal)
{
- mnVerticalOffset = -(nAvailableHeight
+ mnVerticalOffset = round(-(nHeight
- mnRowCount*maPreviewSize.Height - (mnRowCount-1)*mnVerticalGap)
- / 2;
+ / 2);
mnHorizontalOffset = 0;
}
else
{
mnVerticalOffset = 0;
- mnHorizontalOffset = -(nAvailableWidth
- - mnColumnCount*maPreviewSize.Width - (mnColumnCount-1)*mnHorizontalGap)
- / 2;
+ mnHorizontalOffset = round(-(nWidth
+ - mnColumnCount*maPreviewSize.Width
+ - (mnColumnCount-1)*mnHorizontalGap)
+ / 2);
}
-
- SetupVisibleArea();
- UpdateScrollBars();
}
@@ -1016,59 +1401,118 @@ void PresenterSlideSorter::Layout::Update (
void PresenterSlideSorter::Layout::SetupVisibleArea (void)
{
- geometry::RealPoint2D aPoint (0,0);
+ geometry::RealPoint2D aPoint (GetLocalPosition(
+ geometry::RealPoint2D(maBoundingBox.X1, maBoundingBox.Y1)));
if (meOrientation == Horizontal)
{
- mnFirstVisibleColumn = ::std::max(
- sal_Int32(0),
- sal_Int32((aPoint.X + mnHorizontalOffset + mnHorizontalGap)
- / (maPreviewSize.Width+mnHorizontalGap)));
+ mnFirstVisibleColumn = ::std::max(sal_Int32(0), GetColumn(aPoint));
mnFirstVisibleRow = 0;
}
else
{
mnFirstVisibleColumn = 0;
- mnFirstVisibleRow = ::std::max(
- sal_Int32(0),
- sal_Int32((aPoint.Y + mnVerticalOffset + mnVerticalGap)
- / (maPreviewSize.Height+mnVerticalGap)));
+ mnFirstVisibleRow = ::std::max(sal_Int32(0), GetRow(aPoint));
}
- aPoint = geometry::RealPoint2D(maViewport.X2-maViewport.X1, maViewport.Y2-maViewport.Y1);
+ aPoint = GetLocalPosition(geometry::RealPoint2D( maBoundingBox.X2, maBoundingBox.Y2));
if (meOrientation == Horizontal)
{
- mnLastVisibleColumn = sal_Int32((aPoint.X + mnHorizontalOffset)
- / (maPreviewSize.Width+mnHorizontalGap));
+ mnLastVisibleColumn = GetColumn(aPoint, true);
mnLastVisibleRow = mnRowCount - 1;
}
else
{
mnLastVisibleColumn = mnColumnCount - 1;
- mnLastVisibleRow = sal_Int32((aPoint.Y + mnVerticalOffset)
- / (maPreviewSize.Height+mnVerticalGap));
+ mnLastVisibleRow = GetRow(aPoint, true);
}
}
-sal_Int32 PresenterSlideSorter::Layout::GetSlideIndexForPosition (
- const css::geometry::RealPoint2D& rPoint)
+bool PresenterSlideSorter::Layout::IsScrollBarNeeded (const sal_Int32 nSlideCount)
{
- if (rPoint.X < maViewport.X1
- || rPoint.X > maViewport.X2
- || rPoint.Y < maViewport.Y1
- || rPoint.Y > maViewport.Y2)
+ geometry::RealPoint2D aBottomRight;
+ if (GetOrientation() == Layout::Vertical)
+ aBottomRight = GetPoint(
+ mnColumnCount * (GetRow(nSlideCount)+1) - 1, +1, +1);
+ else
+ aBottomRight = GetPoint(
+ mnRowCount * (GetColumn(nSlideCount)+1) - 1, +1, +1);
+ return aBottomRight.X > maBoundingBox.X2-maBoundingBox.X1
+ || aBottomRight.Y > maBoundingBox.Y2-maBoundingBox.Y1;
+}
+
+
+
+
+geometry::RealPoint2D PresenterSlideSorter::Layout::GetLocalPosition(
+ const geometry::RealPoint2D& rWindowPoint) const
+{
+ return css::geometry::RealPoint2D(
+ rWindowPoint.X - maBoundingBox.X1 + mnHorizontalOffset,
+ rWindowPoint.Y - maBoundingBox.Y1 + mnVerticalOffset);
+}
+
+
+
+
+geometry::RealPoint2D PresenterSlideSorter::Layout::GetWindowPosition(
+ const geometry::RealPoint2D& rLocalPoint) const
+{
+ return css::geometry::RealPoint2D(
+ rLocalPoint.X - mnHorizontalOffset + maBoundingBox.X1,
+ rLocalPoint.Y - mnVerticalOffset + maBoundingBox.Y1);
+}
+
+
+
+
+sal_Int32 PresenterSlideSorter::Layout::GetColumn (
+ const css::geometry::RealPoint2D& rLocalPoint,
+ const bool bReturnInvalidValue) const
+{
+ const sal_Int32 nColumn(floor(
+ (rLocalPoint.X + mnHorizontalGap/2.0) / (maPreviewSize.Width+mnHorizontalGap)));
+ if (bReturnInvalidValue
+ || (nColumn>=mnFirstVisibleColumn && nColumn<=mnLastVisibleColumn))
{
+ return nColumn;
+ }
+ else
return -1;
+}
+
+
+
+
+sal_Int32 PresenterSlideSorter::Layout::GetRow (
+ const css::geometry::RealPoint2D& rLocalPoint,
+ const bool bReturnInvalidValue) const
+{
+ const sal_Int32 nRow (floor(
+ (rLocalPoint.Y + mnVerticalGap/2.0) / (maPreviewSize.Height+mnVerticalGap)));
+ if (bReturnInvalidValue
+ || (nRow>=mnFirstVisibleRow && nRow<=mnLastVisibleRow))
+ {
+ return nRow;
}
+ else
+ return -1;
+}
- const double nX (rPoint.X - maViewport.X1 + mnHorizontalOffset);
- const double nY (rPoint.Y - maViewport.Y1 + mnVerticalOffset);
- const sal_Int32 nColumn (sal_Int32(
- (nX + mnHorizontalGap/2.0) / (maPreviewSize.Width+mnHorizontalGap)));
- const sal_Int32 nRow (sal_Int32(
- (nY + mnVerticalGap/2.0) / (maPreviewSize.Height+mnVerticalGap)));
+
+
+
+sal_Int32 PresenterSlideSorter::Layout::GetSlideIndexForPosition (
+ const css::geometry::RealPoint2D& rWindowPoint) const
+{
+ if ( ! PresenterGeometryHelper::IsInside(maBoundingBox, rWindowPoint))
+ return -1;
+
+ const css::geometry::RealPoint2D aLocalPosition (GetLocalPosition(rWindowPoint));
+ const sal_Int32 nColumn (GetColumn(aLocalPosition));
+ const sal_Int32 nRow (GetRow(aLocalPosition));
if (nColumn < 0 || nRow < 0)
return -1;
@@ -1088,14 +1532,14 @@ sal_Int32 PresenterSlideSorter::Layout::GetSlideIndexForPosition (
geometry::RealPoint2D PresenterSlideSorter::Layout::GetPoint (
const sal_Int32 nSlideIndex,
const sal_Int32 nRelativeHorizontalPosition,
- const sal_Int32 nRelativeVerticalPosition)
+ const sal_Int32 nRelativeVerticalPosition) const
{
sal_Int32 nColumn (GetColumn(nSlideIndex));
sal_Int32 nRow (GetRow(nSlideIndex));
- geometry::RealPoint2D aPosition(
- maViewport.X1 + nColumn*(maPreviewSize.Width+mnHorizontalGap) - mnHorizontalOffset,
- maViewport.Y1 + nRow*(maPreviewSize.Height+mnVerticalGap) - mnVerticalOffset);
+ geometry::RealPoint2D aPosition (
+ mnHorizontalBorder + nColumn*(maPreviewSize.Width+mnHorizontalGap),
+ mnVerticalBorder + nRow*(maPreviewSize.Height+mnVerticalGap));
if (nRelativeHorizontalPosition >= 0)
if (nRelativeHorizontalPosition > 0)
@@ -1112,47 +1556,25 @@ geometry::RealPoint2D PresenterSlideSorter::Layout::GetPoint (
}
-namespace { double sqr (const double nValue) { return nValue*nValue; } }
-double PresenterSlideSorter::Layout::GetDistanceFromCenter (
- const css::geometry::RealPoint2D& rPoint,
- const sal_Int32 nSlideIndex,
- const DistanceType eDistanceType)
-{
- const geometry::RealPoint2D aCenter (GetPoint(nSlideIndex, 0,0));
-
- switch (eDistanceType)
- {
- case Norm1:
- default:
- return ::std::max(
- fabs(rPoint.X - aCenter.X) / maPreviewSize.Width * 2,
- fabs(rPoint.Y - aCenter.Y) / maPreviewSize.Height * 2);
-
- case Norm2:
- return sqrt(
- sqr((rPoint.X - aCenter.X) / maPreviewSize.Width * 2)
- + sqr((rPoint.Y - aCenter.Y) / maPreviewSize.Height * 2));
- case XOnly:
- return fabs(rPoint.X - aCenter.X) / maPreviewSize.Width * 2;
-
- case YOnly:
- return fabs(rPoint.Y - aCenter.Y) / maPreviewSize.Height * 2;
- }
+awt::Rectangle PresenterSlideSorter::Layout::GetBoundingBox (const sal_Int32 nSlideIndex) const
+{
+ const geometry::RealPoint2D aWindowPosition(GetWindowPosition(GetPoint(nSlideIndex, -1, -1)));
+ return PresenterGeometryHelper::ConvertRectangle(
+ geometry::RealRectangle2D(
+ aWindowPosition.X,
+ aWindowPosition.Y,
+ aWindowPosition.X + maPreviewSize.Width,
+ aWindowPosition.Y + maPreviewSize.Height));
}
-awt::Rectangle PresenterSlideSorter::Layout::GetBoundingBox (const sal_Int32 nSlideIndex)
+geometry::IntegerSize2D PresenterSlideSorter::Layout::GetPreviewSize (void) const
{
- const geometry::RealPoint2D aPosition(GetPoint(nSlideIndex, 0, 0));
- return awt::Rectangle (
- sal_Int32(floor(aPosition.X)),
- sal_Int32(floor(aPosition.Y)),
- sal_Int32(ceil(aPosition.X + maPreviewSize.Width) - floor(aPosition.X)),
- sal_Int32(ceil(aPosition.Y + maPreviewSize.Height) - floor(aPosition.Y)));
+ return maPreviewSize;
}
@@ -1175,7 +1597,7 @@ void PresenterSlideSorter::Layout::ForAllVisibleSlides (const ::boost::function<
-sal_Int32 PresenterSlideSorter::Layout::GetFirstVisibleSlideIndex (void)
+sal_Int32 PresenterSlideSorter::Layout::GetFirstVisibleSlideIndex (void) const
{
return GetIndex(mnFirstVisibleRow, mnFirstVisibleColumn);
}
@@ -1183,7 +1605,7 @@ sal_Int32 PresenterSlideSorter::Layout::GetFirstVisibleSlideIndex (void)
-sal_Int32 PresenterSlideSorter::Layout::GetLastVisibleSlideIndex (void)
+sal_Int32 PresenterSlideSorter::Layout::GetLastVisibleSlideIndex (void) const
{
return ::std::min(
GetIndex(mnLastVisibleRow, mnLastVisibleColumn),
@@ -1197,7 +1619,7 @@ bool PresenterSlideSorter::Layout::SetHorizontalOffset (const double nOffset)
{
if (mnHorizontalOffset != nOffset)
{
- mnHorizontalOffset = nOffset;
+ mnHorizontalOffset = round(nOffset);
SetupVisibleArea();
UpdateScrollBars();
return true;
@@ -1209,6 +1631,31 @@ bool PresenterSlideSorter::Layout::SetHorizontalOffset (const double nOffset)
+bool PresenterSlideSorter::Layout::SetVerticalOffset (const double nOffset)
+{
+ if (mnVerticalOffset != nOffset)
+ {
+ mnVerticalOffset = round(nOffset);
+ SetupVisibleArea();
+ UpdateScrollBars();
+ return true;
+ }
+ else
+ return false;
+}
+
+
+
+
+PresenterSlideSorter::Layout::Orientation
+ PresenterSlideSorter::Layout::GetOrientation (void) const
+{
+ return meOrientation;
+}
+
+
+
+
void PresenterSlideSorter::Layout::UpdateScrollBars (void)
{
sal_Int32 nTotalColumnCount (0);
@@ -1227,30 +1674,23 @@ void PresenterSlideSorter::Layout::UpdateScrollBars (void)
if (mpHorizontalScrollBar.get() != NULL)
{
mpHorizontalScrollBar->SetTotalSize(
- nTotalColumnCount * maPreviewSize.Width + (nTotalColumnCount-1) * mnHorizontalGap);
- mpHorizontalScrollBar->SetThumbPosition(mnHorizontalOffset);
- mpHorizontalScrollBar->SetThumbSize(
- mnColumnCount * (maPreviewSize.Width + mnHorizontalGap) - mnHorizontalGap);
+ nTotalColumnCount * maPreviewSize.Width
+ + (nTotalColumnCount-1) * mnHorizontalGap
+ + 2*mnHorizontalBorder);
+ mpHorizontalScrollBar->SetThumbPosition(mnHorizontalOffset, false);
+ mpHorizontalScrollBar->SetThumbSize(maBoundingBox.X2 - maBoundingBox.X1 + 1);
}
if (mpVerticalScrollBar.get() != NULL)
{
mpVerticalScrollBar->SetTotalSize(
- nTotalRowCount * maPreviewSize.Height + (nTotalRowCount-1) * mnVerticalGap);
- mpVerticalScrollBar->SetThumbPosition(mnVerticalOffset);
- mpVerticalScrollBar->SetThumbSize(
- mnRowCount * (maPreviewSize.Height + mnVerticalGap) - mnVerticalGap);
+ nTotalRowCount * maPreviewSize.Height
+ + (nTotalRowCount-1) * mnVerticalGap
+ + 2*mnVerticalGap);
+ mpVerticalScrollBar->SetThumbPosition(mnVerticalOffset, false);
+ mpVerticalScrollBar->SetThumbSize(maBoundingBox.Y2 - maBoundingBox.Y1 + 1);
}
- // Place the scroll bars.
- if (mpHorizontalScrollBar.get() != NULL)
- {
- mpHorizontalScrollBar->SetPosSize(geometry::RealRectangle2D(
- maViewport.X1,
- maViewport.Y2 + maInnerBorder.Y2,
- maViewport.X2,
- maViewport.Y2 + maInnerBorder.Y2 + mnScrollBarHeight));
- }
// No place yet for the vertical scroll bar.
}
@@ -1258,7 +1698,9 @@ void PresenterSlideSorter::Layout::UpdateScrollBars (void)
-sal_Int32 PresenterSlideSorter::Layout::GetIndex (const sal_Int32 nRow, const sal_Int32 nColumn)
+sal_Int32 PresenterSlideSorter::Layout::GetIndex (
+ const sal_Int32 nRow,
+ const sal_Int32 nColumn) const
{
if (meOrientation == Horizontal)
return nColumn * mnRowCount + nRow;
@@ -1269,7 +1711,7 @@ sal_Int32 PresenterSlideSorter::Layout::GetIndex (const sal_Int32 nRow, const sa
-sal_Int32 PresenterSlideSorter::Layout::GetRow (const sal_Int32 nSlideIndex)
+sal_Int32 PresenterSlideSorter::Layout::GetRow (const sal_Int32 nSlideIndex) const
{
if (meOrientation == Horizontal)
return nSlideIndex % mnRowCount;
@@ -1280,7 +1722,7 @@ sal_Int32 PresenterSlideSorter::Layout::GetRow (const sal_Int32 nSlideIndex)
-sal_Int32 PresenterSlideSorter::Layout::GetColumn (const sal_Int32 nSlideIndex)
+sal_Int32 PresenterSlideSorter::Layout::GetColumn (const sal_Int32 nSlideIndex) const
{
if (meOrientation == Horizontal)
return nSlideIndex / mnRowCount;
@@ -1294,29 +1736,32 @@ sal_Int32 PresenterSlideSorter::Layout::GetColumn (const sal_Int32 nSlideIndex)
//===== PresenterSlideSorter::MouseOverManager ================================
PresenterSlideSorter::MouseOverManager::MouseOverManager (
- const Reference<XComponentContext>& rxContext,
const Reference<container::XIndexAccess>& rxSlides,
- const Reference<frame::XModel>& rxModel)
- : MouseOverManagerInterfaceBase(m_aMutex),
- mxCanvas(),
- mxPreviewCache(),
+ const ::boost::shared_ptr<PresenterTheme>& rpTheme,
+ const Reference<awt::XWindow>& rxInvalidateTarget,
+ const ::boost::shared_ptr<PresenterPaintManager>& rpPaintManager)
+ : mxCanvas(),
+ mxSlides(rxSlides),
+ mpLeftLabelBitmap(),
+ mpCenterLabelBitmap(),
+ mpRightLabelBitmap(),
+ mpFont(),
mnSlideIndex(-1),
- mnDistance(2),
- mxSprite(NULL),
- maSpriteSize(0,0),
- mbIsActive(true)
+ maSlideBoundingBox(),
+ mxInvalidateTarget(rxInvalidateTarget),
+ mpPaintManager(rpPaintManager)
{
- Reference<lang::XMultiComponentFactory> xFactory (rxContext->getServiceManager(), UNO_QUERY);
- if (xFactory.is())
+ if (rpTheme.get()!=NULL)
{
- // Create the preview cache.
- mxPreviewCache = Reference<drawing::XSlidePreviewCache>(
- xFactory->createInstanceWithContext(
- OUString::createFromAscii("com.sun.star.drawing.PresenterPreviewCache"),
- rxContext),
- UNO_QUERY_THROW);
- mxPreviewCache->setDocumentSlides(rxSlides, rxModel);
- mxPreviewCache->addPreviewCreationNotifyListener(this);
+ ::boost::shared_ptr<PresenterBitmapContainer> pBitmaps (rpTheme->GetBitmapContainer());
+ if (pBitmaps.get() != NULL)
+ {
+ mpLeftLabelBitmap = pBitmaps->GetBitmap(A2S("LabelLeft"));
+ mpCenterLabelBitmap = pBitmaps->GetBitmap(A2S("LabelCenter"));
+ mpRightLabelBitmap = pBitmaps->GetBitmap(A2S("LabelRight"));
+ }
+
+ mpFont = rpTheme->GetFont(A2S("SlideSorterLabelFont"));
}
}
@@ -1325,29 +1770,43 @@ PresenterSlideSorter::MouseOverManager::MouseOverManager (
PresenterSlideSorter::MouseOverManager::~MouseOverManager (void)
{
- Reference<lang::XComponent> xComponent (mxPreviewCache, UNO_QUERY);
- mxPreviewCache = NULL;
- if (xComponent.is())
- xComponent->dispose();
-
- DisposeSprite();
}
-void PresenterSlideSorter::MouseOverManager::DisposeSprite (void)
+void PresenterSlideSorter::MouseOverManager::Paint (
+ const sal_Int32 nSlideIndex,
+ const Reference<rendering::XCanvas>& rxCanvas,
+ const Reference<rendering::XPolyPolygon2D>& rxClip)
{
- if (mxSprite.is())
- {
- mxSprite->hide();
- if (mxCanvas.is())
- mxCanvas->updateScreen(sal_False);
+ if (nSlideIndex != mnSlideIndex)
+ return;
- Reference<lang::XComponent> xComponent (mxSprite, UNO_QUERY);
- mxSprite = NULL;
- if (xComponent.is())
- xComponent->dispose();
+ if (mxCanvas != rxCanvas)
+ SetCanvas(rxCanvas);
+ if (rxCanvas != NULL)
+ {
+ if ( ! mxBitmap.is())
+ mxBitmap = CreateBitmap(msText, maSlideBoundingBox.Width);
+ if (mxBitmap.is())
+ {
+ geometry::IntegerSize2D aSize (mxBitmap->getSize());
+ const double nXOffset (maSlideBoundingBox.X
+ + (maSlideBoundingBox.Width - aSize.Width) / 2.0);
+ const double nYOffset (maSlideBoundingBox.Y
+ + (maSlideBoundingBox.Height - aSize.Height) / 2.0);
+ rxCanvas->drawBitmap(
+ mxBitmap,
+ rendering::ViewState(
+ geometry::AffineMatrix2D(1,0,0, 0,1,0),
+ rxClip),
+ rendering::RenderState(
+ geometry::AffineMatrix2D(1,0,nXOffset, 0,1,nYOffset),
+ NULL,
+ Sequence<double>(3),
+ rendering::CompositeOperation::SOURCE));
+ }
}
}
@@ -1355,9 +1814,11 @@ void PresenterSlideSorter::MouseOverManager::DisposeSprite (void)
void PresenterSlideSorter::MouseOverManager::SetCanvas (
- const Reference<rendering::XSpriteCanvas>& rxCanvas)
+ const Reference<rendering::XCanvas>& rxCanvas)
{
mxCanvas = rxCanvas;
+ if (mpFont.get() != NULL)
+ mpFont->PrepareFont(Reference<rendering::XCanvas>(mxCanvas, UNO_QUERY));
}
@@ -1365,140 +1826,507 @@ void PresenterSlideSorter::MouseOverManager::SetCanvas (
void PresenterSlideSorter::MouseOverManager::SetSlide (
const sal_Int32 nSlideIndex,
- const awt::Rectangle& rBox,
- const double nDistance)
-{
- mnDistance = nDistance;
- if ( ! mxSprite.is()
- || nSlideIndex != mnSlideIndex
- || rBox.X != maBoundingBox.X
- || rBox.Y != maBoundingBox.Y)
- {
- DisposeSprite();
- mnSlideIndex = nSlideIndex;
- maBoundingBox = rBox;
-
- if (mnSlideIndex < 0)
- return;
-
- if ( ! mbIsActive)
- return;
-
- CreateSprite(nSlideIndex);
- if ( ! mxSprite.is())
- return;
-
- mxSprite->move(
- geometry::RealPoint2D(maBoundingBox.X, maBoundingBox.Y),
- rendering::ViewState(
- geometry::AffineMatrix2D(1,0,0, 0,1,0),
- NULL),
- rendering::RenderState(
- geometry::AffineMatrix2D(1,0,0, 0,1,0),
- NULL,
- Sequence<double>(3),
- rendering::CompositeOperation::SOURCE)
- );
- }
-
- if ( ! mxSprite.is())
+ const awt::Rectangle& rBox)
+{
+ if (mnSlideIndex == nSlideIndex)
return;
- double nDownScale (maBoundingBox.Width / maSpriteSize.Width);
- double nUpScale (1.0);
- if (nDistance < 1.0)
- if (nDistance < 0.8)
- nUpScale = mnMaxScale;
- else
+ mnSlideIndex = -1;
+ Invalidate();
+
+ maSlideBoundingBox = rBox;
+ mnSlideIndex = nSlideIndex;
+
+ if (nSlideIndex >= 0)
+ {
+ if (mxSlides.get() != NULL)
{
- const double nWeight ((nDistance-0.8) / 0.2);
- nUpScale = mnMinScale*nWeight + mnMaxScale*(1-nWeight);
- }
+ msText = OUString();
- double nScale (nDownScale * nUpScale);
- mxSprite->transform(
- geometry::AffineMatrix2D(
- nScale,0, - nScale*maSpriteSize.Width/2.0,
- 0,nScale, - nScale*maSpriteSize.Height/2.0));
+ Reference<beans::XPropertySet> xSlideProperties(mxSlides->getByIndex(nSlideIndex), UNO_QUERY);
+ if (xSlideProperties.is())
+ xSlideProperties->getPropertyValue(A2S("LinkDisplayName")) >>= msText;
- mxCanvas->updateScreen(sal_False);
+ if (msText.getLength() == 0)
+ msText = A2S("Slide ") + OUString::valueOf(nSlideIndex + 1);
+ }
+ }
+ else
+ {
+ msText = OUString();
+ }
+ mxBitmap = NULL;
+
+ Invalidate();
}
-void PresenterSlideSorter::MouseOverManager::SetActiveState (const bool bIsActive)
+Reference<rendering::XBitmap> PresenterSlideSorter::MouseOverManager::CreateBitmap (
+ const OUString& rsText,
+ const sal_Int32 nMaximalWidth) const
{
- if (mbIsActive != bIsActive)
+ if ( ! mxCanvas.is())
+ return NULL;
+
+ if (mpFont.get()==NULL || !mpFont->mxFont.is())
+ return NULL;
+
+ // Long text has to be shortened.
+ const OUString sText (GetFittingText(rsText, nMaximalWidth
+ - 2*gnHorizontalLabelBorder
+ - 2*gnHorizontalLabelPadding));
+
+ // Determine the size of the label. Its height is defined by the
+ // bitmaps that are used to paints its background. The width is defined
+ // by the text.
+ geometry::IntegerSize2D aLabelSize (CalculateLabelSize(sText));
+
+ // Create a new bitmap that will contain the complete label.
+ Reference<rendering::XBitmap> xBitmap (
+ mxCanvas->getDevice()->createCompatibleAlphaBitmap(aLabelSize));
+
+ if ( ! xBitmap.is())
+ return NULL;
+
+ Reference<rendering::XBitmapCanvas> xBitmapCanvas (xBitmap->queryBitmapCanvas());
+ if ( ! xBitmapCanvas.is())
+ return NULL;
+
+ // Paint the background.
+ PaintButtonBackground(xBitmapCanvas, aLabelSize);
+
+ // Paint the text.
+ if (sText.getLength() > 0)
{
- mbIsActive = bIsActive;
- if ( ! mbIsActive)
- DisposeSprite();
- else if (mnSlideIndex >= 0)
- SetSlide (mnSlideIndex, maBoundingBox, mnDistance);
+
+ const rendering::StringContext aContext (sText, 0, sText.getLength());
+ const Reference<rendering::XTextLayout> xLayout (mpFont->mxFont->createTextLayout(
+ aContext, rendering::TextDirection::WEAK_LEFT_TO_RIGHT,0));
+ const geometry::RealRectangle2D aTextBBox (xLayout->queryTextBounds());
+
+ const double nXOffset = (aLabelSize.Width - aTextBBox.X2 + aTextBBox.X1) / 2;
+ const double nYOffset = aLabelSize.Height
+ - (aLabelSize.Height - aTextBBox.Y2 + aTextBBox.Y1)/2 - aTextBBox.Y2;
+
+ const rendering::ViewState aViewState(
+ geometry::AffineMatrix2D(1,0,0, 0,1,0),
+ NULL);
+
+ rendering::RenderState aRenderState (
+ geometry::AffineMatrix2D(1,0,nXOffset, 0,1,nYOffset),
+ NULL,
+ Sequence<double>(3),
+ rendering::CompositeOperation::SOURCE);
+ PresenterCanvasHelper::SetDeviceColor(aRenderState, mpFont->mnColor);
+
+ xBitmapCanvas->drawText(
+ aContext,
+ mpFont->mxFont,
+ aViewState,
+ aRenderState,
+ rendering::TextDirection::WEAK_LEFT_TO_RIGHT);
}
+
+ return xBitmap;
}
-void PresenterSlideSorter::MouseOverManager::CreateSprite (const sal_Int32 nSlideIndex)
+OUString PresenterSlideSorter::MouseOverManager::GetFittingText (
+ const OUString& rsText,
+ const double nMaximalWidth) const
{
- if ( ! mxPreviewCache.is())
- return;
- maSpriteSize = geometry::RealSize2D(maBoundingBox.Width*2, maBoundingBox.Height*2);
- mxPreviewCache->setPreviewSize(geometry::IntegerSize2D(
- sal_Int32(maSpriteSize.Width), sal_Int32(maSpriteSize.Height)));
- if (mxCanvas.is() && ! mxSprite.is())
+ const double nTextWidth (
+ PresenterCanvasHelper::GetTextSize(mpFont->mxFont, rsText).Width);
+ if (nTextWidth > nMaximalWidth)
{
- mxSprite = mxCanvas->createCustomSprite(maSpriteSize);
- if (mxSprite.is())
+ // Text is too wide. Shorten it by removing characters from the end
+ // and replacing them by ellipses.
+
+ // Guess a start value of the final string length.
+ double nBestWidth (0);
+ OUString sBestCandidate;
+ sal_Int32 nLength (round(rsText.getLength() * nMaximalWidth / nTextWidth));
+ const OUString sEllipses (A2S("..."));
+ while (true)
{
- mxSprite->setAlpha(1.0);
- mxSprite->setPriority(+10);
- mxSprite->show();
+ const OUString sCandidate (rsText.copy(0,nLength) + sEllipses);
+ const double nWidth (
+ PresenterCanvasHelper::GetTextSize(mpFont->mxFont, sCandidate).Width);
+ if (nWidth > nMaximalWidth)
+ {
+ // Candidate still too wide, shorten it.
+ nLength -= 1;
+ if (nLength <= 0)
+ break;
+ }
+ else if (nWidth < nMaximalWidth)
+ {
+ // Candidate short enough.
+ if (nWidth > nBestWidth)
+ {
+ // Best length so far.
+ sBestCandidate = sCandidate;
+ nBestWidth = nWidth;
+ nLength += 1;
+ if (nLength >= rsText.getLength())
+ break;
+ }
+ else
+ break;
+ }
+ else
+ {
+ // Candidate is exactly as long as it may be. Use it
+ // without looking any further.
+ sBestCandidate = sCandidate;
+ break;
+ }
}
+ return sBestCandidate;
}
- if (mxSprite.is())
- {
- Reference<rendering::XCanvas> xSpriteCanvas (mxSprite->getContentCanvas());
- if (xSpriteCanvas.is())
- {
- Reference<rendering::XBitmap> xBitmap (
- mxPreviewCache->getSlidePreview(nSlideIndex, xSpriteCanvas));
- if (xBitmap.is())
- {
- rendering::ViewState aViewState(
- geometry::AffineMatrix2D(1,0,0, 0,1,0),
- NULL);
+ else
+ return rsText;
+}
- rendering::RenderState aRenderState (
- geometry::AffineMatrix2D(1,0,0, 0,1,0),
- NULL,
- Sequence<double>(3),
- rendering::CompositeOperation::SOURCE);
- xSpriteCanvas->drawBitmap(xBitmap, aViewState, aRenderState);
- }
- }
+
+geometry::IntegerSize2D PresenterSlideSorter::MouseOverManager::CalculateLabelSize (
+ const OUString& rsText) const
+{
+ // Height is specified by the label bitmaps.
+ sal_Int32 nHeight (32);
+ if (mpCenterLabelBitmap.get() != NULL)
+ {
+ Reference<rendering::XBitmap> xBitmap (mpCenterLabelBitmap->GetNormalBitmap());
+ if (xBitmap.is())
+ nHeight = xBitmap->getSize().Height;
}
+
+ // Width is specified by text width and maximal width.
+ const geometry::RealSize2D aTextSize (
+ PresenterCanvasHelper::GetTextSize(mpFont->mxFont, rsText));
+
+ const sal_Int32 nWidth (round(aTextSize.Width + 2*gnHorizontalLabelPadding));
+
+ return geometry::IntegerSize2D(nWidth, nHeight);
}
-void SAL_CALL PresenterSlideSorter::MouseOverManager::notifyPreviewCreation (
- sal_Int32 nSlideIndex)
- throw(css::uno::RuntimeException)
+void PresenterSlideSorter::MouseOverManager::PaintButtonBackground (
+ const Reference<rendering::XBitmapCanvas>& rxCanvas,
+ const geometry::IntegerSize2D& rSize) const
{
- if (nSlideIndex == mnSlideIndex)
+ // Get the bitmaps for painting the label background.
+ Reference<rendering::XBitmap> xLeftLabelBitmap;
+ if (mpLeftLabelBitmap.get() != NULL)
+ xLeftLabelBitmap = mpLeftLabelBitmap->GetNormalBitmap();
+
+ Reference<rendering::XBitmap> xCenterLabelBitmap;
+ if (mpCenterLabelBitmap.get() != NULL)
+ xCenterLabelBitmap = mpCenterLabelBitmap->GetNormalBitmap();
+
+ Reference<rendering::XBitmap> xRightLabelBitmap;
+ if (mpRightLabelBitmap.get() != NULL)
+ xRightLabelBitmap = mpRightLabelBitmap->GetNormalBitmap();
+
+ PresenterUIPainter::PaintHorizontalBitmapComposite (
+ Reference<rendering::XCanvas>(rxCanvas, UNO_QUERY),
+ awt::Rectangle(0,0, rSize.Width,rSize.Height),
+ awt::Rectangle(0,0, rSize.Width,rSize.Height),
+ xLeftLabelBitmap,
+ xCenterLabelBitmap,
+ xRightLabelBitmap);
+}
+
+
+
+
+void PresenterSlideSorter::MouseOverManager::Invalidate (void)
+{
+ if (mpPaintManager.get() != NULL)
+ mpPaintManager->Invalidate(mxInvalidateTarget, maSlideBoundingBox, true);
+}
+
+
+
+
+//===== PresenterSlideSorter::CurrentSlideFrameRenderer =======================
+
+PresenterSlideSorter::CurrentSlideFrameRenderer::CurrentSlideFrameRenderer (
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext,
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas)
+ : mpTopLeft(),
+ mpTop(),
+ mpTopRight(),
+ mpLeft(),
+ mpRight(),
+ mpBottomLeft(),
+ mpBottom(),
+ mpBottomRight(),
+ mnTopFrameSize(0),
+ mnLeftFrameSize(0),
+ mnRightFrameSize(0),
+ mnBottomFrameSize(0)
+{
+ PresenterConfigurationAccess aConfiguration (
+ rxContext,
+ OUString::createFromAscii("/org.openoffice.Office.extension.PresenterScreen/"),
+ PresenterConfigurationAccess::READ_ONLY);
+ Reference<container::XHierarchicalNameAccess> xBitmaps (
+ aConfiguration.GetConfigurationNode(
+ A2S("PresenterScreenSettings/SlideSorter/CurrentSlideBorderBitmaps")),
+ UNO_QUERY);
+ if ( ! xBitmaps.is())
+ return;
+
+ PresenterBitmapContainer aContainer (
+ A2S("PresenterScreenSettings/SlideSorter/CurrentSlideBorderBitmaps"),
+ ::boost::shared_ptr<PresenterBitmapContainer>(),
+ rxContext,
+ rxCanvas,
+ PresenterComponent::GetBasePath(rxContext));
+
+ mpTopLeft = aContainer.GetBitmap(A2S("TopLeft"));
+ mpTop = aContainer.GetBitmap(A2S("Top"));
+ mpTopRight = aContainer.GetBitmap(A2S("TopRight"));
+ mpLeft = aContainer.GetBitmap(A2S("Left"));
+ mpRight = aContainer.GetBitmap(A2S("Right"));
+ mpBottomLeft = aContainer.GetBitmap(A2S("BottomLeft"));
+ mpBottom = aContainer.GetBitmap(A2S("Bottom"));
+ mpBottomRight = aContainer.GetBitmap(A2S("BottomRight"));
+
+ // Determine size of frame.
+ if (mpTop.get() != NULL)
+ mnTopFrameSize = mpTop->mnHeight;
+ if (mpLeft.get() != NULL)
+ mnLeftFrameSize = mpLeft->mnWidth;
+ if (mpRight.get() != NULL)
+ mnRightFrameSize = mpRight->mnWidth;
+ if (mpBottom.get() != NULL)
+ mnBottomFrameSize = mpBottom->mnHeight;
+
+ if (mpTopLeft.get() != NULL)
+ {
+ mnTopFrameSize = ::std::max(mnTopFrameSize, mpTopLeft->mnHeight);
+ mnLeftFrameSize = ::std::max(mnLeftFrameSize, mpTopLeft->mnWidth);
+ }
+ if (mpTopRight.get() != NULL)
+ {
+ mnTopFrameSize = ::std::max(mnTopFrameSize, mpTopRight->mnHeight);
+ mnRightFrameSize = ::std::max(mnRightFrameSize, mpTopRight->mnWidth);
+ }
+ if (mpBottomLeft.get() != NULL)
{
- CreateSprite(mnSlideIndex);
+ mnLeftFrameSize = ::std::max(mnLeftFrameSize, mpBottomLeft->mnWidth);
+ mnBottomFrameSize = ::std::max(mnBottomFrameSize, mpBottomLeft->mnHeight);
+ }
+ if (mpBottomRight.get() != NULL)
+ {
+ mnRightFrameSize = ::std::max(mnRightFrameSize, mpBottomRight->mnWidth);
+ mnBottomFrameSize = ::std::max(mnBottomFrameSize, mpBottomRight->mnHeight);
+ }
+}
- Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY);
- if (xSpriteCanvas.is())
- xSpriteCanvas->updateScreen(sal_False);
+
+
+
+PresenterSlideSorter::CurrentSlideFrameRenderer::~CurrentSlideFrameRenderer (void)
+{
+}
+
+
+
+
+void PresenterSlideSorter::CurrentSlideFrameRenderer::PaintCurrentSlideFrame (
+ const awt::Rectangle& rSlideBoundingBox,
+ const Reference<rendering::XCanvas>& rxCanvas,
+ const geometry::RealRectangle2D& rClipBox)
+{
+ if ( ! rxCanvas.is())
+ return;
+
+ const Reference<rendering::XPolyPolygon2D> xClip (
+ PresenterGeometryHelper::CreatePolygon(rClipBox, rxCanvas->getDevice()));
+
+ if (mpTop.get() != NULL)
+ {
+ PaintBitmapTiled(
+ mpTop->GetNormalBitmap(),
+ rxCanvas,
+ rClipBox,
+ rSlideBoundingBox.X,
+ rSlideBoundingBox.Y - mpTop->mnHeight,
+ rSlideBoundingBox.Width,
+ mpTop->mnHeight);
+ }
+ if (mpLeft.get() != NULL)
+ {
+ PaintBitmapTiled(
+ mpLeft->GetNormalBitmap(),
+ rxCanvas,
+ rClipBox,
+ rSlideBoundingBox.X - mpLeft->mnWidth,
+ rSlideBoundingBox.Y,
+ mpLeft->mnWidth,
+ rSlideBoundingBox.Height);
+ }
+ if (mpRight.get() != NULL)
+ {
+ PaintBitmapTiled(
+ mpRight->GetNormalBitmap(),
+ rxCanvas,
+ rClipBox,
+ rSlideBoundingBox.X + rSlideBoundingBox.Width,
+ rSlideBoundingBox.Y,
+ mpRight->mnWidth,
+ rSlideBoundingBox.Height);
+ }
+ if (mpBottom.get() != NULL)
+ {
+ PaintBitmapTiled(
+ mpBottom->GetNormalBitmap(),
+ rxCanvas,
+ rClipBox,
+ rSlideBoundingBox.X,
+ rSlideBoundingBox.Y + rSlideBoundingBox.Height,
+ rSlideBoundingBox.Width,
+ mpBottom->mnHeight);
+ }
+ if (mpTopLeft.get() != NULL)
+ {
+ PaintBitmapOnce(
+ mpTopLeft->GetNormalBitmap(),
+ rxCanvas,
+ xClip,
+ rSlideBoundingBox.X - mpTopLeft->mnWidth,
+ rSlideBoundingBox.Y - mpTopLeft->mnHeight);
+ }
+ if (mpTopRight.get() != NULL)
+ {
+ PaintBitmapOnce(
+ mpTopRight->GetNormalBitmap(),
+ rxCanvas,
+ xClip,
+ rSlideBoundingBox.X + rSlideBoundingBox.Width,
+ rSlideBoundingBox.Y - mpTopLeft->mnHeight);
+ }
+ if (mpBottomLeft.get() != NULL)
+ {
+ PaintBitmapOnce(
+ mpBottomLeft->GetNormalBitmap(),
+ rxCanvas,
+ xClip,
+ rSlideBoundingBox.X - mpBottomLeft->mnWidth,
+ rSlideBoundingBox.Y + rSlideBoundingBox.Height);
+ }
+ if (mpBottomRight.get() != NULL)
+ {
+ PaintBitmapOnce(
+ mpBottomRight->GetNormalBitmap(),
+ rxCanvas,
+ xClip,
+ rSlideBoundingBox.X + rSlideBoundingBox.Width,
+ rSlideBoundingBox.Y + rSlideBoundingBox.Height);
}
}
+
+
+
+awt::Rectangle PresenterSlideSorter::CurrentSlideFrameRenderer::GetBoundingBox (
+ const awt::Rectangle& rSlideBoundingBox)
+{
+ return awt::Rectangle(
+ rSlideBoundingBox.X - mnLeftFrameSize,
+ rSlideBoundingBox.Y - mnTopFrameSize,
+ rSlideBoundingBox.Width + mnLeftFrameSize + mnRightFrameSize,
+ rSlideBoundingBox.Height + mnTopFrameSize + mnBottomFrameSize);
+}
+
+
+
+
+void PresenterSlideSorter::CurrentSlideFrameRenderer::PaintBitmapOnce(
+ const css::uno::Reference<css::rendering::XBitmap>& rxBitmap,
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
+ const Reference<rendering::XPolyPolygon2D>& rxClip,
+ const double nX,
+ const double nY)
+{
+ OSL_ASSERT(rxCanvas.is());
+ if ( ! rxBitmap.is())
+ return;
+
+ const rendering::ViewState aViewState(
+ geometry::AffineMatrix2D(1,0,0, 0,1,0),
+ rxClip);
+
+ const rendering::RenderState aRenderState (
+ geometry::AffineMatrix2D(
+ 1, 0, nX,
+ 0, 1, nY),
+ NULL,
+ Sequence<double>(3),
+ rendering::CompositeOperation::SOURCE);
+
+ rxCanvas->drawBitmap(
+ rxBitmap,
+ aViewState,
+ aRenderState);
+}
+
+
+
+
+void PresenterSlideSorter::CurrentSlideFrameRenderer::PaintBitmapTiled(
+ const css::uno::Reference<css::rendering::XBitmap>& rxBitmap,
+ const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
+ const geometry::RealRectangle2D& rClipBox,
+ const double nX0,
+ const double nY0,
+ const double nWidth,
+ const double nHeight)
+{
+ OSL_ASSERT(rxCanvas.is());
+ if ( ! rxBitmap.is())
+ return;
+
+ geometry::IntegerSize2D aSize (rxBitmap->getSize());
+
+ const rendering::ViewState aViewState(
+ geometry::AffineMatrix2D(1,0,0, 0,1,0),
+ PresenterGeometryHelper::CreatePolygon(
+ PresenterGeometryHelper::Intersection(
+ rClipBox,
+ geometry::RealRectangle2D(nX0,nY0,nX0+nWidth,nY0+nHeight)),
+ rxCanvas->getDevice()));
+
+ rendering::RenderState aRenderState (
+ geometry::AffineMatrix2D(
+ 1, 0, nX0,
+ 0, 1, nY0),
+ NULL,
+ Sequence<double>(3),
+ rendering::CompositeOperation::SOURCE);
+
+ const double nX1 = nX0 + nWidth;
+ const double nY1 = nY0 + nHeight;
+ for (double nY=nY0; nY<nY1; nY+=aSize.Height)
+ for (double nX=nX0; nX<nX1; nX+=aSize.Width)
+ {
+ aRenderState.AffineTransform.m02 = nX;
+ aRenderState.AffineTransform.m12 = nY;
+ rxCanvas->drawBitmap(
+ rxBitmap,
+ aViewState,
+ aRenderState);
+ }
+}
+
} } // end of namespace ::sdext::presenter