bump product version to 6.3.0.0.beta1
[LibreOffice.git] / sdext / source / presenter / PresenterSlidePreview.cxx
blobb81c42660b50620b671b6b23139e1c0a4dfce9a1
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "PresenterSlidePreview.hxx"
21 #include "PresenterCanvasHelper.hxx"
22 #include "PresenterGeometryHelper.hxx"
23 #include "PresenterPaintManager.hxx"
24 #include "PresenterScrollBar.hxx"
25 #include "PresenterBitmapContainer.hxx"
26 #include <com/sun/star/awt/XWindow.hpp>
27 #include <com/sun/star/awt/XWindowPeer.hpp>
28 #include <com/sun/star/beans/XPropertySet.hpp>
29 #include <com/sun/star/drawing/framework/XConfigurationController.hpp>
30 #include <com/sun/star/drawing/framework/XControllerManager.hpp>
31 #include <com/sun/star/drawing/framework/XPane.hpp>
32 #include <com/sun/star/rendering/CompositeOperation.hpp>
34 using namespace ::com::sun::star;
35 using namespace ::com::sun::star::uno;
36 using namespace ::com::sun::star::drawing::framework;
38 namespace
40 // Use a super sample factor greater than 1 to achieve a poor mans
41 // antialiasing effect for slide previews.
42 const sal_Int16 gnSuperSampleFactor = 2;
45 namespace sdext { namespace presenter {
47 //===== PresenterSlidePreview =================================================
49 PresenterSlidePreview::PresenterSlidePreview (
50 const Reference<XComponentContext>& rxContext,
51 const Reference<XResourceId>& rxViewId,
52 const Reference<XPane>& rxAnchorPane,
53 const ::rtl::Reference<PresenterController>& rpPresenterController)
54 : PresenterSlidePreviewInterfaceBase(m_aMutex),
55 mpPresenterController(rpPresenterController),
56 mxViewId(rxViewId),
57 mxPreviewRenderer(),
58 mxPreview(),
59 mxCurrentSlide(),
60 mnSlideAspectRatio(28.0 / 21.0),
61 mxWindow(),
62 mxCanvas()
64 if ( ! rxContext.is()
65 || ! rxViewId.is()
66 || ! rxAnchorPane.is()
67 || ! rpPresenterController.is())
69 throw RuntimeException(
70 "PresenterSlidePreview can not be constructed due to empty argument",
71 static_cast<XWeak*>(this));
74 mxWindow = rxAnchorPane->getWindow();
75 mxCanvas = rxAnchorPane->getCanvas();
77 if (mxWindow.is())
79 mxWindow->addWindowListener(this);
80 mxWindow->addPaintListener(this);
82 Reference<awt::XWindowPeer> xPeer (mxWindow, UNO_QUERY);
83 if (xPeer.is())
84 xPeer->setBackground(util::Color(0xff000000));
86 mxWindow->setVisible(true);
89 if (mpPresenterController.get() != nullptr)
90 mnSlideAspectRatio = mpPresenterController->GetSlideAspectRatio();
92 Reference<lang::XMultiComponentFactory> xFactory (rxContext->getServiceManager(), UNO_QUERY);
93 if (xFactory.is())
94 mxPreviewRenderer.set(
95 xFactory->createInstanceWithContext(
96 "com.sun.star.drawing.SlideRenderer",
97 rxContext),
98 UNO_QUERY);
99 mpBitmaps.reset(new PresenterBitmapContainer(
100 "PresenterScreenSettings/ScrollBar/Bitmaps",
101 std::shared_ptr<PresenterBitmapContainer>(),
102 rxContext,
103 mxCanvas));
104 Resize();
107 PresenterSlidePreview::~PresenterSlidePreview()
111 void SAL_CALL PresenterSlidePreview::disposing()
113 if (mxWindow.is())
115 mxWindow->removeWindowListener(this);
116 mxWindow->removePaintListener(this);
117 mxWindow = nullptr;
118 mxCanvas = nullptr;
121 Reference<lang::XComponent> xComponent (mxPreviewRenderer, UNO_QUERY);
122 if (xComponent.is())
123 xComponent->dispose();
126 //----- XResourceId -----------------------------------------------------------
128 Reference<XResourceId> SAL_CALL PresenterSlidePreview::getResourceId()
130 return mxViewId;
133 sal_Bool SAL_CALL PresenterSlidePreview::isAnchorOnly()
135 return false;
138 //----- XWindowListener -------------------------------------------------------
140 void SAL_CALL PresenterSlidePreview::windowResized (const awt::WindowEvent&)
142 ThrowIfDisposed();
143 ::osl::MutexGuard aGuard (::osl::Mutex::getGlobalMutex());
144 Resize();
147 void SAL_CALL PresenterSlidePreview::windowMoved (const awt::WindowEvent&) {}
149 void SAL_CALL PresenterSlidePreview::windowShown (const lang::EventObject&)
151 ThrowIfDisposed();
152 ::osl::MutexGuard aGuard (::osl::Mutex::getGlobalMutex());
153 Resize();
156 void SAL_CALL PresenterSlidePreview::windowHidden (const lang::EventObject&) {}
158 //----- XPaintListener --------------------------------------------------------
160 void SAL_CALL PresenterSlidePreview::windowPaint (const awt::PaintEvent& rEvent)
162 ThrowIfDisposed();
164 ::osl::MutexGuard aGuard (::osl::Mutex::getGlobalMutex());
165 if (mxWindow.is())
166 Paint(awt::Rectangle(
167 rEvent.UpdateRect.X,
168 rEvent.UpdateRect.Y,
169 rEvent.UpdateRect.Width,
170 rEvent.UpdateRect.Height));
173 //----- lang::XEventListener --------------------------------------------------
175 void SAL_CALL PresenterSlidePreview::disposing (const lang::EventObject& rEvent)
177 if (rEvent.Source == mxWindow)
179 mxWindow = nullptr;
180 mxCanvas = nullptr;
181 mxPreview = nullptr;
185 //----- XDrawView -------------------------------------------------------------
187 void SAL_CALL PresenterSlidePreview::setCurrentPage (const Reference<drawing::XDrawPage>& rxSlide)
189 ThrowIfDisposed();
190 ::osl::MutexGuard aGuard (::osl::Mutex::getGlobalMutex());
191 SetSlide(rxSlide);
194 Reference<drawing::XDrawPage> SAL_CALL PresenterSlidePreview::getCurrentPage()
196 ThrowIfDisposed();
197 return nullptr;
201 void PresenterSlidePreview::SetSlide (const Reference<drawing::XDrawPage>& rxPage)
203 mxCurrentSlide = rxPage;
204 mxPreview = nullptr;
206 // The preview is not transparent, therefore only this window, not its
207 // parent, has to be invalidated.
208 mpPresenterController->GetPaintManager()->Invalidate(mxWindow);
211 void PresenterSlidePreview::Paint (const awt::Rectangle& rBoundingBox)
213 if ( ! mxWindow.is())
214 return;
215 if ( ! mxCanvas.is())
216 return;
217 if ( ! mxPreviewRenderer.is())
218 return;
220 // Make sure that a preview in the correct size exists.
221 awt::Rectangle aWindowBox (mxWindow->getPosSize());
223 bool bCustomAnimation = false;
224 bool bTransition = false;
225 if( mxCurrentSlide.is() )
227 bCustomAnimation = PresenterController::HasCustomAnimation(mxCurrentSlide);
228 bTransition = PresenterController::HasTransition(mxCurrentSlide);
231 if ( ! mxPreview.is() && mxCurrentSlide.is())
233 // Create a new preview bitmap.
234 mxPreview = mxPreviewRenderer->createPreviewForCanvas(
235 mxCurrentSlide,
236 awt::Size(aWindowBox.Width, aWindowBox.Height),
237 gnSuperSampleFactor,
238 mxCanvas);
241 // Determine the bounding box of the preview.
242 awt::Rectangle aPreviewBox;
243 if (mxPreview.is())
245 const geometry::IntegerSize2D aPreviewSize (mxPreview->getSize());
246 aPreviewBox = awt::Rectangle(
247 (aWindowBox.Width - aPreviewSize.Width)/2,
248 (aWindowBox.Height - aPreviewSize.Height)/2,
249 aPreviewSize.Width,
250 aPreviewSize.Height);
252 else
254 if (mnSlideAspectRatio > 0)
256 const awt::Size aPreviewSize (mxPreviewRenderer->calculatePreviewSize(
257 mnSlideAspectRatio,awt::Size(aWindowBox.Width, aWindowBox.Height)));
258 aPreviewBox = awt::Rectangle(
259 (aWindowBox.Width - aPreviewSize.Width)/2,
260 (aWindowBox.Height - aPreviewSize.Height)/2,
261 aPreviewSize.Width,
262 aPreviewSize.Height);
266 // Paint the background.
267 mpPresenterController->GetCanvasHelper()->Paint(
268 mpPresenterController->GetViewBackground(mxViewId->getResourceURL()),
269 mxCanvas,
270 rBoundingBox,
271 awt::Rectangle(0,0,aWindowBox.Width,aWindowBox.Height),
272 aPreviewBox);
274 // Paint the preview.
275 const rendering::ViewState aViewState(
276 geometry::AffineMatrix2D(1,0,0, 0,1,0),
277 nullptr);
279 Sequence<double> aBackgroundColor(4);
280 rendering::RenderState aRenderState (
281 geometry::AffineMatrix2D(1, 0, aPreviewBox.X, 0, 1, aPreviewBox.Y),
282 nullptr,
283 aBackgroundColor,
284 rendering::CompositeOperation::SOURCE);
285 PresenterCanvasHelper::SetDeviceColor(aRenderState, 0x00000000);
286 if (mxPreview.is())
288 mxCanvas->drawBitmap(mxPreview, aViewState, aRenderState);
289 if( bTransition )
291 const awt::Rectangle aTransitionPreviewBox(5, aWindowBox.Height-20, 0, 0);
292 SharedBitmapDescriptor aTransitionDescriptor = mpBitmaps->GetBitmap("Transition");
293 Reference<rendering::XBitmap> xTransitionIcon (aTransitionDescriptor->GetNormalBitmap());
294 rendering::RenderState aTransitionRenderState (
295 geometry::AffineMatrix2D(1, 0, aTransitionPreviewBox.X, 0, 1, aTransitionPreviewBox.Y),
296 nullptr,
297 aBackgroundColor,
298 rendering::CompositeOperation::SOURCE);
299 mxCanvas->drawBitmap(xTransitionIcon, aViewState, aTransitionRenderState);
301 if( bCustomAnimation )
303 const awt::Rectangle aAnimationPreviewBox(5, aWindowBox.Height-40, 0, 0);
304 SharedBitmapDescriptor aAnimationDescriptor = mpBitmaps->GetBitmap("Animation");
305 Reference<rendering::XBitmap> xAnimationIcon (aAnimationDescriptor->GetNormalBitmap());
306 rendering::RenderState aAnimationRenderState (
307 geometry::AffineMatrix2D(1, 0, aAnimationPreviewBox.X, 0, 1, aAnimationPreviewBox.Y),
308 nullptr,
309 aBackgroundColor,
310 rendering::CompositeOperation::SOURCE);
311 mxCanvas->drawBitmap(xAnimationIcon, aViewState, aAnimationRenderState);
314 else
316 if (mnSlideAspectRatio > 0)
318 Reference<rendering::XPolyPolygon2D> xPolygon (
319 PresenterGeometryHelper::CreatePolygon(aPreviewBox, mxCanvas->getDevice()));
320 if (xPolygon.is())
321 mxCanvas->fillPolyPolygon(xPolygon, aViewState, aRenderState);
325 Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY);
326 if (xSpriteCanvas.is())
327 xSpriteCanvas->updateScreen(false);
330 void PresenterSlidePreview::Resize()
332 if (mxPreviewRenderer.is() && mxPreview.is())
334 const awt::Rectangle aWindowBox (mxWindow->getPosSize());
335 const awt::Size aNewPreviewSize (mxPreviewRenderer->calculatePreviewSize(
336 mnSlideAspectRatio,
337 awt::Size(aWindowBox.Width, aWindowBox.Height)));
338 const geometry::IntegerSize2D aPreviewSize (mxPreview->getSize());
339 if (aNewPreviewSize.Width==aPreviewSize.Width
340 && aNewPreviewSize.Height==aPreviewSize.Height)
342 // The size of the window may have changed but the preview would
343 // be painted in the same size (but not necessarily at the same
344 // position.)
345 return;
348 SetSlide(mxCurrentSlide);
351 void PresenterSlidePreview::ThrowIfDisposed()
353 if (PresenterSlidePreviewInterfaceBase::rBHelper.bDisposed || PresenterSlidePreviewInterfaceBase::rBHelper.bInDispose)
355 throw lang::DisposedException (
356 "PresenterSlidePreview object has already been disposed",
357 static_cast<uno::XWeak*>(this));
361 } } // end of namespace ::sd::presenter
363 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */