Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include "PresenterPaneBase.hxx"
21 : #include "PresenterCanvasHelper.hxx"
22 : #include "PresenterController.hxx"
23 : #include "PresenterGeometryHelper.hxx"
24 : #include "PresenterPaintManager.hxx"
25 : #include "PresenterTextView.hxx"
26 : #include <com/sun/star/awt/PosSize.hpp>
27 : #include <com/sun/star/awt/XWindow2.hpp>
28 : #include <com/sun/star/awt/XWindowPeer.hpp>
29 : #include <com/sun/star/lang/XMultiComponentFactory.hpp>
30 : #include <com/sun/star/drawing/CanvasFeature.hpp>
31 : #include <com/sun/star/rendering/CompositeOperation.hpp>
32 : #include <com/sun/star/rendering/TexturingMode.hpp>
33 : #include <osl/mutex.hxx>
34 :
35 : using namespace css;
36 : using namespace css::uno;
37 : using namespace css::drawing::framework;
38 :
39 : namespace sdext { namespace presenter {
40 :
41 : //===== PresenterPaneBase =====================================================
42 :
43 0 : PresenterPaneBase::PresenterPaneBase (
44 : const Reference<XComponentContext>& rxContext,
45 : const ::rtl::Reference<PresenterController>& rpPresenterController)
46 : : PresenterPaneBaseInterfaceBase(m_aMutex),
47 : mpPresenterController(rpPresenterController),
48 : mxParentWindow(),
49 : mxBorderWindow(),
50 : mxBorderCanvas(),
51 : mxContentWindow(),
52 : mxContentCanvas(),
53 : mxPaneId(),
54 : mxBorderPainter(),
55 : mxPresenterHelper(),
56 : msTitle(),
57 : mxComponentContext(rxContext),
58 : mpViewBackground(),
59 : mbHasCallout(false),
60 0 : maCalloutAnchor()
61 : {
62 0 : if (mpPresenterController.get() != NULL)
63 0 : mxPresenterHelper = mpPresenterController->GetPresenterHelper();
64 0 : }
65 :
66 0 : PresenterPaneBase::~PresenterPaneBase()
67 : {
68 0 : }
69 :
70 0 : void PresenterPaneBase::disposing()
71 : {
72 0 : if (mxBorderWindow.is())
73 : {
74 0 : mxBorderWindow->removeWindowListener(this);
75 0 : mxBorderWindow->removePaintListener(this);
76 : }
77 :
78 : {
79 0 : Reference<XComponent> xComponent (mxContentCanvas, UNO_QUERY);
80 0 : mxContentCanvas = NULL;
81 0 : if (xComponent.is())
82 0 : xComponent->dispose();
83 : }
84 :
85 : {
86 0 : Reference<XComponent> xComponent (mxContentWindow, UNO_QUERY);
87 0 : mxContentWindow = NULL;
88 0 : if (xComponent.is())
89 0 : xComponent->dispose();
90 : }
91 :
92 : {
93 0 : Reference<XComponent> xComponent (mxBorderCanvas, UNO_QUERY);
94 0 : mxBorderCanvas = NULL;
95 0 : if (xComponent.is())
96 0 : xComponent->dispose();
97 : }
98 :
99 : {
100 0 : Reference<XComponent> xComponent (mxBorderWindow, UNO_QUERY);
101 0 : mxBorderWindow = NULL;
102 0 : if (xComponent.is())
103 0 : xComponent->dispose();
104 : }
105 :
106 0 : mxComponentContext = NULL;
107 0 : }
108 :
109 0 : void PresenterPaneBase::SetTitle (const OUString& rsTitle)
110 : {
111 0 : msTitle = rsTitle;
112 :
113 : OSL_ASSERT(mpPresenterController.get()!=NULL);
114 : OSL_ASSERT(mpPresenterController->GetPaintManager().get()!=NULL);
115 :
116 0 : mpPresenterController->GetPaintManager()->Invalidate(mxBorderWindow);
117 0 : }
118 :
119 0 : OUString PresenterPaneBase::GetTitle() const
120 : {
121 0 : return msTitle;
122 : }
123 :
124 : Reference<drawing::framework::XPaneBorderPainter>
125 0 : PresenterPaneBase::GetPaneBorderPainter() const
126 : {
127 0 : return mxBorderPainter;
128 : }
129 :
130 0 : void PresenterPaneBase::SetCalloutAnchor (const css::awt::Point& rCalloutAnchor)
131 : {
132 0 : mbHasCallout = true;
133 : // Anchor is given in the coorindate system of the parent window.
134 : // Transform it into the local coordinate system.
135 0 : maCalloutAnchor = rCalloutAnchor;
136 0 : const awt::Rectangle aBorderBox (mxBorderWindow->getPosSize());
137 0 : maCalloutAnchor.X -= aBorderBox.X;
138 0 : maCalloutAnchor.Y -= aBorderBox.Y;
139 :
140 : // Move the bottom of the border window so that it goes through the
141 : // callout anchor (special case for bottom callout).
142 0 : sal_Int32 nHeight (rCalloutAnchor.Y - aBorderBox.Y);
143 0 : if (mxBorderPainter.is() && mxPaneId.is())
144 0 : nHeight += mxBorderPainter->getCalloutOffset(mxPaneId->getResourceURL()).Y;
145 :
146 0 : if (nHeight != aBorderBox.Height)
147 : {
148 0 : mxBorderWindow->setPosSize(
149 : aBorderBox.X,
150 : aBorderBox.Y,
151 : aBorderBox.Width,
152 : nHeight,
153 0 : awt::PosSize::HEIGHT);
154 : }
155 :
156 0 : mpPresenterController->GetPaintManager()->Invalidate(mxBorderWindow);
157 0 : }
158 :
159 0 : awt::Point PresenterPaneBase::GetCalloutAnchor() const
160 : {
161 0 : return maCalloutAnchor;
162 : }
163 :
164 : //----- XInitialization -------------------------------------------------------
165 :
166 0 : void SAL_CALL PresenterPaneBase::initialize (const Sequence<Any>& rArguments)
167 : throw (Exception, RuntimeException, std::exception)
168 : {
169 0 : ThrowIfDisposed();
170 :
171 0 : if ( ! mxComponentContext.is())
172 : {
173 : throw RuntimeException(
174 : "PresenterSpritePane: missing component context",
175 0 : static_cast<XWeak*>(this));
176 : }
177 :
178 0 : if (rArguments.getLength() == 5 || rArguments.getLength() == 6)
179 : {
180 : try
181 : {
182 : // Get the resource id from the first argument.
183 0 : if ( ! (rArguments[0] >>= mxPaneId))
184 : {
185 : throw lang::IllegalArgumentException(
186 : "PresenterPane: invalid pane id",
187 : static_cast<XWeak*>(this),
188 0 : 0);
189 : }
190 :
191 0 : if ( ! (rArguments[1] >>= mxParentWindow))
192 : {
193 : throw lang::IllegalArgumentException(
194 : "PresenterPane: invalid parent window",
195 : static_cast<XWeak*>(this),
196 0 : 1);
197 : }
198 :
199 0 : Reference<rendering::XSpriteCanvas> xParentCanvas;
200 0 : if ( ! (rArguments[2] >>= xParentCanvas))
201 : {
202 : throw lang::IllegalArgumentException(
203 : "PresenterPane: invalid parent canvas",
204 : static_cast<XWeak*>(this),
205 0 : 2);
206 : }
207 :
208 0 : if ( ! (rArguments[3] >>= msTitle))
209 : {
210 : throw lang::IllegalArgumentException(
211 : "PresenterPane: invalid title",
212 : static_cast<XWeak*>(this),
213 0 : 3);
214 : }
215 :
216 0 : if ( ! (rArguments[4] >>= mxBorderPainter))
217 : {
218 : throw lang::IllegalArgumentException(
219 : "PresenterPane: invalid border painter",
220 : static_cast<XWeak*>(this),
221 0 : 4);
222 : }
223 :
224 0 : bool bIsWindowVisibleOnCreation (true);
225 0 : if (rArguments.getLength()>5 && ! (rArguments[5] >>= bIsWindowVisibleOnCreation))
226 : {
227 : throw lang::IllegalArgumentException(
228 : "PresenterPane: invalid window visibility flag",
229 : static_cast<XWeak*>(this),
230 0 : 5);
231 : }
232 :
233 0 : CreateWindows(mxParentWindow, bIsWindowVisibleOnCreation);
234 :
235 0 : if (mxBorderWindow.is())
236 : {
237 0 : mxBorderWindow->addWindowListener(this);
238 0 : mxBorderWindow->addPaintListener(this);
239 : }
240 :
241 0 : CreateCanvases(mxParentWindow, xParentCanvas);
242 :
243 : // Raise new windows.
244 0 : ToTop();
245 : }
246 0 : catch (Exception&)
247 : {
248 0 : mxContentWindow = NULL;
249 0 : mxComponentContext = NULL;
250 0 : throw;
251 : }
252 : }
253 : else
254 : {
255 : throw RuntimeException(
256 : "PresenterSpritePane: invalid number of arguments",
257 0 : static_cast<XWeak*>(this));
258 : }
259 0 : }
260 :
261 : //----- XResourceId -----------------------------------------------------------
262 :
263 0 : Reference<XResourceId> SAL_CALL PresenterPaneBase::getResourceId()
264 : throw (RuntimeException, std::exception)
265 : {
266 0 : ThrowIfDisposed();
267 0 : return mxPaneId;
268 : }
269 :
270 0 : sal_Bool SAL_CALL PresenterPaneBase::isAnchorOnly()
271 : throw (RuntimeException, std::exception)
272 : {
273 0 : return true;
274 : }
275 :
276 : //----- XWindowListener -------------------------------------------------------
277 :
278 0 : void SAL_CALL PresenterPaneBase::windowResized (const awt::WindowEvent& rEvent)
279 : throw (RuntimeException, std::exception)
280 : {
281 : (void)rEvent;
282 0 : ThrowIfDisposed();
283 0 : }
284 :
285 0 : void SAL_CALL PresenterPaneBase::windowMoved (const awt::WindowEvent& rEvent)
286 : throw (RuntimeException, std::exception)
287 : {
288 : (void)rEvent;
289 0 : ThrowIfDisposed();
290 0 : }
291 :
292 0 : void SAL_CALL PresenterPaneBase::windowShown (const lang::EventObject& rEvent)
293 : throw (RuntimeException, std::exception)
294 : {
295 : (void)rEvent;
296 0 : ThrowIfDisposed();
297 0 : }
298 :
299 0 : void SAL_CALL PresenterPaneBase::windowHidden (const lang::EventObject& rEvent)
300 : throw (RuntimeException, std::exception)
301 : {
302 : (void)rEvent;
303 0 : ThrowIfDisposed();
304 0 : }
305 :
306 : //----- lang::XEventListener --------------------------------------------------
307 :
308 0 : void SAL_CALL PresenterPaneBase::disposing (const lang::EventObject& rEvent)
309 : throw (RuntimeException, std::exception)
310 : {
311 0 : if (rEvent.Source == mxBorderWindow)
312 : {
313 0 : mxBorderWindow = NULL;
314 : }
315 0 : }
316 :
317 :
318 :
319 0 : void PresenterPaneBase::CreateWindows (
320 : const Reference<awt::XWindow>& rxParentWindow,
321 : const bool bIsWindowVisibleOnCreation)
322 : {
323 0 : if (mxPresenterHelper.is() && rxParentWindow.is())
324 : {
325 :
326 0 : mxBorderWindow = mxPresenterHelper->createWindow(
327 : rxParentWindow,
328 : sal_False,
329 : bIsWindowVisibleOnCreation,
330 : sal_False,
331 0 : sal_False);
332 0 : mxContentWindow = mxPresenterHelper->createWindow(
333 : mxBorderWindow,
334 : sal_False,
335 : bIsWindowVisibleOnCreation,
336 : sal_False,
337 0 : sal_False);
338 : }
339 0 : }
340 :
341 0 : Reference<awt::XWindow> PresenterPaneBase::GetBorderWindow() const
342 : {
343 0 : return mxBorderWindow;
344 : }
345 :
346 0 : void PresenterPaneBase::ToTop()
347 : {
348 0 : if (mxPresenterHelper.is())
349 0 : mxPresenterHelper->toTop(mxContentWindow);
350 0 : }
351 :
352 0 : void PresenterPaneBase::SetBackground (const SharedBitmapDescriptor& rpBackground)
353 : {
354 0 : mpViewBackground = rpBackground;
355 0 : }
356 :
357 0 : void PresenterPaneBase::PaintBorderBackground (
358 : const awt::Rectangle& rBorderBox,
359 : const awt::Rectangle& rUpdateBox)
360 : {
361 : (void)rBorderBox;
362 : (void)rUpdateBox;
363 : /*
364 : // The outer box of the border is given. We need the center and inner
365 : // box as well.
366 : awt::Rectangle aCenterBox (
367 : mxBorderPainter->removeBorder(
368 : mxPaneId->getResourceURL(),
369 : rBorderBox,
370 : drawing::framework::BorderType_OUTER_BORDER));
371 : awt::Rectangle aInnerBox (
372 : mxBorderPainter->removeBorder(
373 : mxPaneId->getResourceURL(),
374 : rBorderBox,
375 : drawing::framework::BorderType_TOTAL_BORDER));
376 : mpPresenterController->GetCanvasHelper()->Paint(
377 : mpViewBackground,
378 : mxBorderCanvas,
379 : rUpdateBox,
380 : aCenterBox,
381 : aInnerBox);
382 : */
383 0 : }
384 :
385 0 : void PresenterPaneBase::PaintBorder (const awt::Rectangle& rUpdateBox)
386 : {
387 : OSL_ASSERT(mxPaneId.is());
388 :
389 0 : if (mxBorderPainter.is() && mxBorderWindow.is() && mxBorderCanvas.is())
390 : {
391 0 : awt::Rectangle aBorderBox (mxBorderWindow->getPosSize());
392 0 : awt::Rectangle aLocalBorderBox (0,0, aBorderBox.Width, aBorderBox.Height);
393 :
394 0 : PaintBorderBackground(aLocalBorderBox, rUpdateBox);
395 :
396 0 : if (mbHasCallout)
397 0 : mxBorderPainter->paintBorderWithCallout(
398 0 : mxPaneId->getResourceURL(),
399 : mxBorderCanvas,
400 : aLocalBorderBox,
401 : rUpdateBox,
402 : msTitle,
403 0 : maCalloutAnchor);
404 : else
405 0 : mxBorderPainter->paintBorder(
406 0 : mxPaneId->getResourceURL(),
407 : mxBorderCanvas,
408 : aLocalBorderBox,
409 : rUpdateBox,
410 0 : msTitle);
411 : }
412 0 : }
413 :
414 0 : void PresenterPaneBase::LayoutContextWindow()
415 : {
416 : OSL_ASSERT(mxPaneId.is());
417 : OSL_ASSERT(mxBorderWindow.is());
418 : OSL_ASSERT(mxContentWindow.is());
419 0 : if (mxBorderPainter.is() && mxPaneId.is() && mxBorderWindow.is() && mxContentWindow.is())
420 : {
421 0 : const awt::Rectangle aBorderBox (mxBorderWindow->getPosSize());
422 0 : const awt::Rectangle aInnerBox (mxBorderPainter->removeBorder(
423 0 : mxPaneId->getResourceURL(),
424 : aBorderBox,
425 0 : drawing::framework::BorderType_TOTAL_BORDER));
426 0 : mxContentWindow->setPosSize(
427 : aInnerBox.X - aBorderBox.X,
428 : aInnerBox.Y - aBorderBox.Y,
429 : aInnerBox.Width,
430 : aInnerBox.Height,
431 0 : awt::PosSize::POSSIZE);
432 : }
433 0 : }
434 :
435 0 : bool PresenterPaneBase::IsVisible() const
436 : {
437 0 : Reference<awt::XWindow2> xWindow2 (mxBorderPainter, UNO_QUERY);
438 0 : if (xWindow2.is())
439 0 : return xWindow2->isVisible();
440 :
441 0 : return false;
442 : }
443 :
444 0 : void PresenterPaneBase::ThrowIfDisposed()
445 : throw (::com::sun::star::lang::DisposedException)
446 : {
447 0 : if (rBHelper.bDisposed || rBHelper.bInDispose)
448 : {
449 : throw lang::DisposedException (
450 : "PresenterPane object has already been disposed",
451 0 : static_cast<uno::XWeak*>(this));
452 : }
453 0 : }
454 :
455 : } } // end of namespace ::sd::presenter
456 :
457 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|